alphabase
Version:
AlphaBase V3.0 - Advanced file-based database with JWT authentication, RSA encryption, audit logging, HTTP server, and comprehensive security features.
371 lines (361 loc) • 12.6 kB
JavaScript
const AlphaBase = require('./alpha');
const AlphaServer = require('./server');
const { JWTAuth, AuditLogger, RSAEncryption } = require('./security');
const AlphaBaseManager = require('./alpha').AlphaBaseManager || null;
const path = require('path');
const fs = require('fs');
const inquirer = require('inquirer');
const boxen = require('boxen');
const yargs = require('yargs/yargs');
function getDbFiles() {
return fs.readdirSync(process.cwd()).filter(f => f.endsWith('.json'));
}
const argv = yargs(process.argv.slice(2))
.option('file', {
alias: 'f',
describe: 'Veritabanı dosya yolu',
type: 'string',
default: 'alphabase.json'
})
.option('password', {
alias: 'p',
describe: 'Veritabanı şifresi (şifreleme için)',
type: 'string'
})
.option('interactive', {
alias: 'i',
describe: 'Etkileşimli mod',
type: 'boolean',
default: false
})
.help()
.parse();
let db = new AlphaBase({ filePath: path.resolve(argv.file), password: argv.password });
let dbManager = AlphaBaseManager ? new AlphaBaseManager() : null;
async function runInteractive() {
let dbFile = argv.file;
let password = argv.password;
while (true) {
const files = getDbFiles();
const { selectedFile } = await inquirer.prompt({
type: 'list',
name: 'selectedFile',
message: 'Veritabanı dosyasını seçin:',
choices: files,
default: dbFile
});
dbFile = selectedFile;
db = new AlphaBase({ filePath: path.resolve(dbFile), password });
const { op } = await inquirer.prompt({
type: 'list',
name: 'op',
message: 'İşlem seçin:',
choices: [
'get', 'set', 'delete', 'has', 'clear', 'all', 'stats', 'import', 'export', 'export-enc', 'import-enc',
'backup', 'begin', 'commit', 'rollback', 'transaction', 'start-cleanup', 'stop-cleanup',
'db-list', 'db-open', 'db-close', 'switch', 'exit']
});
if (op === 'exit') break;
let key = '';
let value = '';
let result;
if (['get', 'set', 'delete', 'has'].includes(op)) {
const keys = Object.keys(db.allSync());
if (op !== 'set') {
const ans = await inquirer.prompt({
type: 'list',
name: 'key',
message: 'Anahtar:',
choices: keys
});
key = ans.key;
} else {
const ans = await inquirer.prompt({
type: 'input',
name: 'key',
message: 'Anahtar (yeni veya mevcut):'
});
key = ans.key;
}
}
if (op === 'set') {
const ans = await inquirer.prompt({
type: 'editor',
name: 'value',
message: 'Değer (JSON):'
});
try {
value = JSON.parse(ans.value);
} catch {
console.log('Geçersiz JSON!');
continue;
}
await db.set(key, value);
result = 'Set: ' + key;
} else if (op === 'get') {
result = db.getSync(key);
} else if (op === 'delete') {
await db.delete(key);
result = 'Deleted: ' + key;
} else if (op === 'has') {
result = db.hasSync(key);
} else if (op === 'clear') {
await db.clear();
result = 'Database cleared';
} else if (op === 'all') {
result = db.allSync();
} else if (op === 'stats') {
result = db.statsSync();
} else if (op === 'import') {
const ans = await inquirer.prompt({
type: 'editor',
name: 'value',
message: 'Import JSON:'
});
try {
value = JSON.parse(ans.value);
} catch {
console.log('Geçersiz JSON!');
continue;
}
db.importSync(value);
result = 'Import successful';
} else if (op === 'export') {
} else if (op === 'export-enc') {
// Export with encryption
const ans = await inquirer.prompt({
type: 'input',
name: 'collection',
message: 'Collection name:'
});
const fileAns = await inquirer.prompt({
type: 'input',
name: 'file',
message: 'Output file path:'
});
try {
db.exportCollection(ans.collection, fileAns.file, { encrypt: true });
result = 'Encrypted export successful';
} catch (e) {
result = 'Export failed: ' + e.message;
}
} else if (op === 'import-enc') {
// Import with auto-decrypt
const ans = await inquirer.prompt({
type: 'input',
name: 'collection',
message: 'Collection name:'
});
const fileAns = await inquirer.prompt({
type: 'input',
name: 'file',
message: 'Input file path:'
});
try {
db.importCollection(ans.collection, fileAns.file);
result = 'Encrypted import successful';
} catch (e) {
result = 'Import failed: ' + e.message;
}
} else if (op === 'begin') {
db.beginTransaction();
result = 'Transaction started';
} else if (op === 'commit') {
db.commit();
result = 'Transaction committed';
} else if (op === 'rollback') {
db.rollback();
result = 'Transaction rolled back';
} else if (op === 'transaction') {
// Batch transaction
const ans = await inquirer.prompt({
type: 'editor',
name: 'ops',
message: 'Batch ops (JSON array):'
});
try {
const ops = JSON.parse(ans.ops);
db.transactionSync(ops);
result = 'Batch transaction successful';
} catch (e) {
result = 'Transaction failed: ' + e.message;
}
} else if (op === 'start-cleanup') {
const ans = await inquirer.prompt({
type: 'input',
name: 'interval',
message: 'Cleanup interval (ms):',
default: 60000
});
db.startScheduledCleanup(Number(ans.interval));
result = 'Scheduled cleanup started';
} else if (op === 'stop-cleanup') {
db.stopScheduledCleanup();
result = 'Scheduled cleanup stopped';
} else if (op === 'db-list') {
if (dbManager) {
result = dbManager.list();
} else {
result = 'Multi-DB manager not available';
}
} else if (op === 'db-open') {
if (dbManager) {
const ans = await inquirer.prompt({
type: 'input',
name: 'file',
message: 'DB file to open:'
});
dbManager.open(ans.file, { password: argv.password });
result = 'DB opened: ' + ans.file;
} else {
result = 'Multi-DB manager not available';
}
} else if (op === 'db-close') {
if (dbManager) {
const ans = await inquirer.prompt({
type: 'input',
name: 'file',
message: 'DB file to close:'
});
dbManager.close(ans.file);
result = 'DB closed: ' + ans.file;
} else {
result = 'Multi-DB manager not available';
}
} else if (op === 'switch') {
if (dbManager) {
const ans = await inquirer.prompt({
type: 'input',
name: 'file',
message: 'Switch to DB file:'
});
db = dbManager.get(ans.file) || new AlphaBase({ filePath: path.resolve(ans.file), password: argv.password });
result = 'Switched to: ' + ans.file;
} else {
result = 'Multi-DB manager not available';
}
result = db.exportSync();
} else if (op === 'backup') {
const backupPath = await db.backup();
result = 'Backup created: ' + backupPath;
}
if (result !== undefined) {
let out;
if (typeof result === 'object') {
out = boxen(JSON.stringify(result, null, 2), { padding: 1, borderColor: 'blue' });
} else {
out = boxen(result.toString(), { padding: 1, borderColor: 'green' });
}
console.log(out);
}
}
}
(async () => {
if (argv.interactive) {
await runInteractive();
return;
}
// ...eski non-interactive mod...
const cmd = argv._[0];
try {
if (cmd === 'set') {
await db.set(argv.key, JSON.parse(argv.value));
console.log('Set:', argv.key);
} else if (cmd === 'get') {
console.log(await db.get(argv.key));
} else if (cmd === 'delete') {
await db.delete(argv.key);
console.log('Deleted:', argv.key);
} else if (cmd === 'has') {
console.log(await db.has(argv.key));
} else if (cmd === 'clear') {
await db.clear();
console.log('Database cleared');
} else if (cmd === 'all') {
console.log(await db.all());
} else if (cmd === 'stats') {
console.log(await db.stats());
} else if (cmd === 'backup') {
console.log('Backup:', await db.backup());
} else if (cmd === 'export') {
console.log(await db.export());
} else if (cmd === 'list-files') {
console.log(getDbFiles());
} else if (cmd === 'switch') {
db = new AlphaBase({ filePath: path.resolve(argv.file), password: argv.password });
console.log('Switched to file:', argv.file);
} else if (cmd === 'server') {
// Security check: Require explicit --allow-server flag
if (!argv.allowServer && !argv['allow-server']) {
console.log('❌ Security: Server start requires explicit permission');
console.log('💡 Add --allow-server flag to start the server:');
console.log(' node cli.js server --allow-server --port 3000');
console.log(' This prevents accidental server exposure.');
return;
}
// Start HTTP server
const serverOptions = {
allowServerStart: true, // Internal permission flag
port: argv.port || 3000,
host: argv.host || 'localhost',
database: argv.file,
password: argv.password,
encryption: argv.encryption || 'AES',
jwtSecret: argv.jwtSecret || 'alphabase-secret',
auth: argv.auth !== false,
audit: argv.audit !== false
};
console.log('🔐 Starting AlphaBase Server with authentication...');
console.log(` Database: ${serverOptions.database}`);
console.log(` Auth: ${serverOptions.auth ? 'Enabled' : 'Disabled'}`);
console.log(` Audit: ${serverOptions.audit ? 'Enabled' : 'Disabled'}`);
const server = new AlphaServer(serverOptions);
server.start();
console.log(`✅ AlphaBase Server started at http://${serverOptions.host}:${serverOptions.port}`);
console.log('🛑 Press Ctrl+C to stop the server');
} else if (cmd === 'token') {
// JWT token operations
if (argv.create) {
const payload = JSON.parse(argv.payload || '{"user":"default"}');
const token = db.createToken(payload);
console.log('Token:', token);
} else if (argv.verify && argv.token) {
const result = db.verifyToken(argv.token);
console.log('Verification result:', result);
} else {
console.log('Usage: --create --payload \'{"user":"name"}\' or --verify --token <token>');
}
} else if (cmd === 'rsa') {
// RSA operations
if (argv.generate) {
const keys = db.generateRSAKeys();
console.log('RSA Keys generated:');
console.log('Public Key:', keys.publicKey);
console.log('Private Key:', keys.privateKey);
} else if (argv.encrypt && argv.data && argv.publicKey) {
const encrypted = db.rsaEncrypt(argv.data, argv.publicKey);
console.log('Encrypted:', encrypted);
} else if (argv.decrypt && argv.data && argv.privateKey) {
const decrypted = db.rsaDecrypt(argv.data, argv.privateKey);
console.log('Decrypted:', decrypted);
} else {
console.log('Usage: --generate or --encrypt --data <data> --publicKey <key> or --decrypt --data <data> --privateKey <key>');
}
} else if (cmd === 'audit') {
// Audit log operations
if (argv.view) {
const logs = db.getAuditLogs();
console.log('Audit Logs:');
logs.forEach(log => {
console.log(`${log.timestamp} - ${log.operation} - ${log.key} - ${log.user}`);
});
} else {
console.log('Usage: --view to show audit logs');
}
} else {
yargs.showHelp();
}
} catch (e) {
console.error('Error:', e.message);
}
})();