mirror of
https://github.com/elder-plinius/LEAKHUB.git
synced 2026-02-12 16:52:53 +00:00
275 lines
8.0 KiB
JavaScript
275 lines
8.0 KiB
JavaScript
// Database abstraction layer for LeakHub
|
|
// Supports both localStorage and future backend APIs
|
|
|
|
class LeakHubDatabase {
|
|
constructor() {
|
|
this.storagePrefix = 'leakhub_';
|
|
this.apiEndpoint = null; // Will be set for backend mode
|
|
this.isBackendMode = false;
|
|
}
|
|
|
|
// Initialize database with optional backend endpoint
|
|
async init(backendUrl = null) {
|
|
if (backendUrl) {
|
|
this.apiEndpoint = backendUrl;
|
|
this.isBackendMode = true;
|
|
console.log('LeakHub: Backend mode enabled');
|
|
} else {
|
|
console.log('LeakHub: Local storage mode enabled');
|
|
}
|
|
}
|
|
|
|
// Generic storage methods
|
|
async get(key) {
|
|
if (this.isBackendMode) {
|
|
return await this._getFromBackend(key);
|
|
} else {
|
|
return this._getFromLocalStorage(key);
|
|
}
|
|
}
|
|
|
|
async set(key, value) {
|
|
if (this.isBackendMode) {
|
|
return await this._setToBackend(key, value);
|
|
} else {
|
|
return this._setToLocalStorage(key, value);
|
|
}
|
|
}
|
|
|
|
async delete(key) {
|
|
if (this.isBackendMode) {
|
|
return await this._deleteFromBackend(key);
|
|
} else {
|
|
return this._deleteFromLocalStorage(key);
|
|
}
|
|
}
|
|
|
|
// LocalStorage methods
|
|
_getFromLocalStorage(key) {
|
|
try {
|
|
const fullKey = this.storagePrefix + key;
|
|
const data = localStorage.getItem(fullKey);
|
|
return data ? JSON.parse(data) : null;
|
|
} catch (error) {
|
|
console.error('Error reading from localStorage:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
_setToLocalStorage(key, value) {
|
|
try {
|
|
const fullKey = this.storagePrefix + key;
|
|
localStorage.setItem(fullKey, JSON.stringify(value));
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error writing to localStorage:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_deleteFromLocalStorage(key) {
|
|
try {
|
|
const fullKey = this.storagePrefix + key;
|
|
localStorage.removeItem(fullKey);
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error deleting from localStorage:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Backend API methods
|
|
async _getFromBackend(key) {
|
|
try {
|
|
const response = await fetch(`${this.apiEndpoint}/data/${key}`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
return await response.json();
|
|
} else {
|
|
console.error('Backend GET error:', response.status);
|
|
return null;
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching from backend:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async _setToBackend(key, value) {
|
|
try {
|
|
const response = await fetch(`${this.apiEndpoint}/data/${key}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(value)
|
|
});
|
|
|
|
return response.ok;
|
|
} catch (error) {
|
|
console.error('Error saving to backend:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async _deleteFromBackend(key) {
|
|
try {
|
|
const response = await fetch(`${this.apiEndpoint}/data/${key}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
|
|
return response.ok;
|
|
} catch (error) {
|
|
console.error('Error deleting from backend:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Specific LeakHub data methods
|
|
async getLeakDatabase() {
|
|
return await this.get('leakDatabase') || [];
|
|
}
|
|
|
|
async setLeakDatabase(data) {
|
|
return await this.set('leakDatabase', data);
|
|
}
|
|
|
|
async getUserStats() {
|
|
return await this.get('userStats') || {};
|
|
}
|
|
|
|
async setUserStats(data) {
|
|
return await this.set('userStats', data);
|
|
}
|
|
|
|
async getLeakRequests() {
|
|
return await this.get('leakRequests') || [];
|
|
}
|
|
|
|
async setLeakRequests(data) {
|
|
return await this.set('leakRequests', data);
|
|
}
|
|
|
|
async getUserVotes() {
|
|
return await this.get('userVotes') || {};
|
|
}
|
|
|
|
async setUserVotes(data) {
|
|
return await this.set('userVotes', data);
|
|
}
|
|
|
|
async getDailyChallenge() {
|
|
return await this.get('dailyChallenge') || null;
|
|
}
|
|
|
|
async setDailyChallenge(data) {
|
|
return await this.set('dailyChallenge', data);
|
|
}
|
|
|
|
async getAverageSimilarity() {
|
|
return await this.get('avgSimilarity') || '0';
|
|
}
|
|
|
|
async setAverageSimilarity(value) {
|
|
return await this.set('avgSimilarity', value);
|
|
}
|
|
|
|
// Export/Import functionality
|
|
async exportData() {
|
|
const data = {
|
|
leakDatabase: await this.getLeakDatabase(),
|
|
userStats: await this.getUserStats(),
|
|
leakRequests: await this.getLeakRequests(),
|
|
userVotes: await this.getUserVotes(),
|
|
dailyChallenge: await this.getDailyChallenge(),
|
|
avgSimilarity: await this.getAverageSimilarity(),
|
|
exportDate: new Date().toISOString(),
|
|
version: '1.0.0'
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
async importData(data) {
|
|
try {
|
|
if (data.leakDatabase) await this.setLeakDatabase(data.leakDatabase);
|
|
if (data.userStats) await this.setUserStats(data.userStats);
|
|
if (data.leakRequests) await this.setLeakRequests(data.leakRequests);
|
|
if (data.userVotes) await this.setUserVotes(data.userVotes);
|
|
if (data.dailyChallenge) await this.setDailyChallenge(data.dailyChallenge);
|
|
if (data.avgSimilarity) await this.setAverageSimilarity(data.avgSimilarity);
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error importing data:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Backup and restore
|
|
async createBackup() {
|
|
const data = await this.exportData();
|
|
const backupKey = `backup_${Date.now()}`;
|
|
await this.set(backupKey, data);
|
|
return backupKey;
|
|
}
|
|
|
|
async restoreBackup(backupKey) {
|
|
const backup = await this.get(backupKey);
|
|
if (backup) {
|
|
return await this.importData(backup);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Analytics and statistics
|
|
async getStatistics() {
|
|
const leakDatabase = await this.getLeakDatabase();
|
|
const userStats = await this.getUserStats();
|
|
|
|
return {
|
|
totalSubmissions: leakDatabase.length,
|
|
uniqueUsers: Object.keys(userStats).length,
|
|
totalScore: Object.values(userStats).reduce((sum, stats) => sum + (stats.totalScore || 0), 0),
|
|
verifiedLeaks: leakDatabase.filter(sub => sub.confidence >= 90).length,
|
|
firstDiscoveries: leakDatabase.filter(sub => sub.isFirstDiscovery).length,
|
|
targetTypes: this._countTargetTypes(leakDatabase),
|
|
recentActivity: this._getRecentActivity(leakDatabase)
|
|
};
|
|
}
|
|
|
|
_countTargetTypes(leakDatabase) {
|
|
const counts = {};
|
|
leakDatabase.forEach(sub => {
|
|
const type = sub.targetType || 'model';
|
|
counts[type] = (counts[type] || 0) + 1;
|
|
});
|
|
return counts;
|
|
}
|
|
|
|
_getRecentActivity(leakDatabase) {
|
|
const now = new Date();
|
|
const oneWeekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
|
|
return leakDatabase.filter(sub =>
|
|
new Date(sub.timestamp) > oneWeekAgo
|
|
).length;
|
|
}
|
|
}
|
|
|
|
// Create global instance
|
|
window.LeakHubDB = new LeakHubDatabase();
|
|
|
|
// Auto-initialize
|
|
window.LeakHubDB.init().then(() => {
|
|
console.log('LeakHub Database initialized');
|
|
});
|