chore: recovery checkpoint - v3.0 API successfully recovered
CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB Recovery Status: - Successfully recovered brainy.ts from compiled JavaScript - All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.) - Neural subsystem intact (562KB embedded patterns, NLP working) - Augmentation pipeline operational (20+ augmentations) - HNSW clustering system complete - Triple Intelligence compiled (needs constructor fix) - Test suite validates functionality Changes preserved: - 898 files with changes from last 3 days - 144,475 insertions - All augmentation improvements - All test coverage enhancements - Complete v3.0 feature set This is a LOCAL checkpoint only - contains recovered work after corruption incident. Created backup in .backups/brainy-full-20250910-151314.tar.gz Branch: recovery-checkpoint-20250910-151433 Date: Wed Sep 10 03:18:04 PM PDT 2025
This commit is contained in:
parent
f65455fb22
commit
8ff382ca3b
895 changed files with 143654 additions and 28268 deletions
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* Security API for Brainy 3.0
|
||||
* Provides encryption, decryption, hashing, and secure storage
|
||||
*/
|
||||
export class SecurityAPI {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
if (config?.encryptionKey) {
|
||||
// Use provided key (must be 32 bytes hex string)
|
||||
this.encryptionKey = this.hexToBytes(config.encryptionKey);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Encrypt data using AES-256-CBC
|
||||
*/
|
||||
async encrypt(data) {
|
||||
const crypto = await import('../universal/crypto.js');
|
||||
// Generate or use existing key
|
||||
const key = this.encryptionKey || crypto.randomBytes(32);
|
||||
const iv = crypto.randomBytes(16);
|
||||
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
|
||||
let encrypted = cipher.update(data, 'utf8', 'hex');
|
||||
encrypted += cipher.final('hex');
|
||||
// Package encrypted data with metadata
|
||||
// In production, store keys separately in a key management service
|
||||
return JSON.stringify({
|
||||
encrypted,
|
||||
key: this.bytesToHex(key),
|
||||
iv: this.bytesToHex(iv),
|
||||
algorithm: 'aes-256-cbc',
|
||||
timestamp: Date.now()
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Decrypt data encrypted with encrypt()
|
||||
*/
|
||||
async decrypt(encryptedData) {
|
||||
const crypto = await import('../universal/crypto.js');
|
||||
try {
|
||||
const parsed = JSON.parse(encryptedData);
|
||||
const { encrypted, key: keyHex, iv: ivHex, algorithm } = parsed;
|
||||
if (algorithm && algorithm !== 'aes-256-cbc') {
|
||||
throw new Error(`Unsupported encryption algorithm: ${algorithm}`);
|
||||
}
|
||||
const key = this.hexToBytes(keyHex);
|
||||
const iv = this.hexToBytes(ivHex);
|
||||
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
||||
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
||||
decrypted += decipher.final('utf8');
|
||||
return decrypted;
|
||||
}
|
||||
catch (error) {
|
||||
throw new Error(`Decryption failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create a one-way hash of data (for passwords, etc)
|
||||
*/
|
||||
async hash(data, algorithm = 'sha256') {
|
||||
const crypto = await import('../universal/crypto.js');
|
||||
const hash = crypto.createHash(algorithm);
|
||||
hash.update(data);
|
||||
return hash.digest('hex');
|
||||
}
|
||||
/**
|
||||
* Compare data with a hash (for password verification)
|
||||
*/
|
||||
async compare(data, hash, algorithm = 'sha256') {
|
||||
const dataHash = await this.hash(data, algorithm);
|
||||
return this.constantTimeCompare(dataHash, hash);
|
||||
}
|
||||
/**
|
||||
* Generate a secure random token
|
||||
*/
|
||||
async generateToken(bytes = 32) {
|
||||
const crypto = await import('../universal/crypto.js');
|
||||
const buffer = crypto.randomBytes(bytes);
|
||||
return this.bytesToHex(buffer);
|
||||
}
|
||||
/**
|
||||
* Derive a key from a password using PBKDF2
|
||||
* Note: Simplified version using hash instead of PBKDF2 which may not be available
|
||||
*/
|
||||
async deriveKey(password, salt, iterations = 100000) {
|
||||
const crypto = await import('../universal/crypto.js');
|
||||
const actualSalt = salt || this.bytesToHex(crypto.randomBytes(32));
|
||||
// Simplified key derivation using repeated hashing
|
||||
// In production, use a proper PBKDF2 implementation
|
||||
let derived = password + actualSalt;
|
||||
for (let i = 0; i < Math.min(iterations, 1000); i++) {
|
||||
const hash = crypto.createHash('sha256');
|
||||
hash.update(derived);
|
||||
derived = hash.digest('hex');
|
||||
}
|
||||
return {
|
||||
key: derived,
|
||||
salt: actualSalt
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Sign data with HMAC
|
||||
*/
|
||||
async sign(data, secret) {
|
||||
const crypto = await import('../universal/crypto.js');
|
||||
const actualSecret = secret || (await this.generateToken());
|
||||
const hmac = crypto.createHmac('sha256', actualSecret);
|
||||
hmac.update(data);
|
||||
return hmac.digest('hex');
|
||||
}
|
||||
/**
|
||||
* Verify HMAC signature
|
||||
*/
|
||||
async verify(data, signature, secret) {
|
||||
const expectedSignature = await this.sign(data, secret);
|
||||
return this.constantTimeCompare(signature, expectedSignature);
|
||||
}
|
||||
// Helper methods
|
||||
hexToBytes(hex) {
|
||||
const matches = hex.match(/.{1,2}/g);
|
||||
if (!matches)
|
||||
throw new Error('Invalid hex string');
|
||||
return new Uint8Array(matches.map(byte => parseInt(byte, 16)));
|
||||
}
|
||||
bytesToHex(bytes) {
|
||||
return Array.from(bytes)
|
||||
.map(b => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
}
|
||||
constantTimeCompare(a, b) {
|
||||
if (a.length !== b.length)
|
||||
return false;
|
||||
let result = 0;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
||||
}
|
||||
return result === 0;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=SecurityAPI.js.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue