Clean: Remove legacy test scripts and directories to improve security and repository cleanliness

This commit is contained in:
ypratama committed 2026-09-02 15:08:57 +07:00
1 parent 996f685065
commit 03c9ce5482
20 files changed
-1341

No files matched your search

-28
View File
@@ -1,28 +0,0 @@
require('dotenv').config({ path: 'd:/Kuliah/DPI/netify-dashboard/.env.local' });
const mongoose = require('mongoose');
async function testFilter() {
await mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0');
console.log("Connected to MongoDB.");
// Using the exact collection name mongoose uses for DeviceStat
const DeviceStat = mongoose.connection.collection('devicestats');
const kantorUUID = 'F6-2V-DT-8A';
const kantorDevices = await DeviceStat.find({ agent_uuid: kantorUUID }).toArray();
console.log(`\nTotal device records saved in Database specifically for Agent Kantor (${kantorUUID}): ${kantorDevices.length}`);
const contaminated = kantorDevices.filter(d => d.ip_address && d.ip_address.startsWith('10.6.'));
console.log(`\nOUT OF THOSE, how many have Balaraja IP (10.6.x.x) despite being tagged as Kantor? ${contaminated.length}`);
if (contaminated.length > 0) {
console.log("Example contaminated IPs in DB under Kantor's UUID:");
console.log(contaminated.slice(0, 5).map(d => `- ${d.ip_address}`).join('\n'));
}
process.exit(0);
}
testFilter();
-44
View File
@@ -1,44 +0,0 @@
const express = require('express');
const mongoose = require('mongoose');
async function testApps() {
await mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0');
const { AppStat } = require('./models/Schemas');
const pipeline = [
{ $match: { site_uuid: '1959bb55_045b_47c7_bbdd_f33b7db197b9' } },
{ $group: {
_id: '$app_label',
download: { $sum: '$download' },
upload: { $sum: '$upload' },
flows: { $sum: '$flows' }
}
},
{ $sort: { download: -1 } },
{ $limit: 10 }
];
const result = await AppStat.aggregate(pipeline);
console.log('Result for Site A:', result);
const pipelineB = [
{ $match: { site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' } },
{ $group: {
_id: '$app_label',
download: { $sum: '$download' },
upload: { $sum: '$upload' },
flows: { $sum: '$flows' }
}
},
{ $sort: { download: -1 } },
{ $limit: 10 }
];
const resultB = await AppStat.aggregate(pipelineB);
console.log('Result for Site B:', resultB);
mongoose.disconnect();
}
testApps();
-39
View File
@@ -1,39 +0,0 @@
const express = require('express');
const mongoose = require('mongoose');
async function testSummary() {
await mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0');
const { Summary } = require('./models/Schemas');
const siteIds = await Summary.distinct('site_uuid', { agent_uuid: null });
const now = new Date();
const delta = 24 * 3600000;
const timeFilter = { $gte: new Date(now.getTime() - delta) };
console.log('Querying with timeFilter:', timeFilter);
const siteSummaries = await Summary.find({
site_uuid: { $in: siteIds },
agent_uuid: null,
timestamp: timeFilter
}).lean();
let bandwidthDown = 0;
let bandwidthUp = 0;
const validSite = siteSummaries.filter(x => x.bandwidth_down > 0 || x.bandwidth_up > 0);
if (validSite.length > 0) {
validSite.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
bandwidthDown = validSite[0].bandwidth_down || 0;
bandwidthUp = validSite[0].bandwidth_up || 0;
}
console.log('Test validSite length:', validSite.length);
console.log('Resulting Bandwidth:', bandwidthDown, bandwidthUp);
mongoose.disconnect();
}
testSummary();
-27
View File
@@ -1,27 +0,0 @@
const mongoose = require('mongoose');
async function testFilter() {
await mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0');
console.log("Connected to MongoDB.");
const kantorUUID = 'F6-2V-DT-8A';
// 1. Check devices specifically tagged with Kantor's UUID
const kantorDevices = await mongoose.connection.collection('device_stats').find({ agent_uuid: kantorUUID }).toArray();
console.log(`\nTotal device records saved in Database specifically for Agent Kantor (${kantorUUID}): ${kantorDevices.length}`);
// 2. See if any of these explicitly-tagged Kantor records have Balaraja's IP (10.6.x.x)
const contaminated = kantorDevices.filter(d => d.ip_address && d.ip_address.startsWith('10.6.'));
console.log(`\nOUT OF THOSE, how many have Balaraja IP (10.6.x.x) despite being tagged as Kantor? ${contaminated.length}`);
if (contaminated.length > 0) {
console.log("Example contaminated IPs in DB under Kantor's UUID:");
console.log(contaminated.slice(0, 5).map(d => `- ${d.ip_address}`).join('\n'));
}
process.exit(0);
}
testFilter();
-175
View File
@@ -1,175 +0,0 @@
// test/agent_geolocation_test.js
const mongoose = require('../backend/node_modules/mongoose');
const path = require('path');
// Load environment variables
require('dotenv').config({ path: path.join(__dirname, '../.env.local') });
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/backone_dpi';
const { CustomAgentLocation, DeviceStat, Flow } = require('../backend/models/Schemas');
let testCount = 0;
let passedCount = 0;
function assert(label, condition) {
testCount++;
if (condition) {
console.log(` ✓ PASSED: ${label}`);
passedCount++;
} else {
console.error(` ✗ FAILED: ${label}`);
}
}
async function runTests() {
console.log('\n=========================================');
console.log(' RUNNING TDD TESTS FOR GEOLOCATION & FLOWS');
console.log('=========================================\n');
try {
// 1. Connect to DB
await mongoose.connect(MONGODB_URI);
console.log('✓ Connected to MongoDB');
// 2. Validate Geolocation Seeding
const count = await CustomAgentLocation.countDocuments();
assert('CustomAgentLocation collection should have seeded documents', count >= 3);
const balarajaLoc = await CustomAgentLocation.findOne({ agent_uuid: 'F6-2V-DT-8A' });
assert('CPI Balaraja Agent location should exist', !!balarajaLoc);
if (balarajaLoc) {
assert('CPI Balaraja latitude matches', balarajaLoc.latitude === -6.2263304);
assert('CPI Balaraja longitude matches', balarajaLoc.longitude === 106.4247322);
assert('CPI Balaraja belongs to SIAB site', balarajaLoc.site_uuid === '6681452d_9cae_4ff4_8ae8_0d504774265e');
}
const cibuburLoc = await CustomAgentLocation.findOne({ agent_uuid: '2F-TF-1D-GK' });
assert('JRP Cibubur Agent location should exist', !!cibuburLoc);
if (cibuburLoc) {
assert('JRP Cibubur latitude matches', cibuburLoc.latitude === -6.3763318);
assert('JRP Cibubur longitude matches', cibuburLoc.longitude === 106.8983017);
}
const ifgLoc = await CustomAgentLocation.findOne({ agent_uuid: '8A-V3-PB-85' });
assert('IFG LT.18 Agent location should exist', !!ifgLoc);
if (ifgLoc) {
assert('IFG LT.18 latitude matches', ifgLoc.latitude === -6.2253265);
assert('IFG LT.18 longitude matches', ifgLoc.longitude === 106.8061484);
}
// 3. Test Location Updates (Simulation of POST API)
const testUuid = 'TEST-AGENT-UUID';
const testSite = 'test-site-uuid';
// Remove if exists
await CustomAgentLocation.deleteOne({ agent_uuid: testUuid });
const updated = await CustomAgentLocation.findOneAndUpdate(
{ agent_uuid: testUuid },
{
agent_uuid: testUuid,
site_uuid: testSite,
latitude: -6.1234,
longitude: 106.1234,
label: 'Test Location Label'
},
{ new: true, upsert: true }
);
assert('Location upsert should return the saved document', !!updated);
assert('Upserted latitude matches', updated.latitude === -6.1234);
assert('Upserted longitude matches', updated.longitude === 106.1234);
assert('Upserted label matches', updated.label === 'Test Location Label');
// 4. Test Location Reset (Simulation of DELETE API)
const delRes = await CustomAgentLocation.deleteOne({ agent_uuid: testUuid });
assert('Location delete should succeed', delRes.deletedCount > 0);
const checkedDel = await CustomAgentLocation.findOne({ agent_uuid: testUuid });
assert('Location should no longer exist after delete', !checkedDel);
// 5. Test Inter-Agent Flow Aggregation Logic
// Let's seed a mock device belonging to Cibubur agent and a flow from Balaraja to Cibubur's device IP.
const mockDestIp = '192.168.99.123';
// Cleanup if existing
await DeviceStat.deleteOne({ ip_address: mockDestIp });
await Flow.deleteMany({ dst_ip: mockDestIp });
// Seed mock device monitored by Cibubur agent (2F-TF-1D-GK)
await DeviceStat.create({
timestamp: new Date(),
ip_address: mockDestIp,
agent_uuid: '2F-TF-1D-GK',
site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e',
mac_address: '00:11:22:33:44:55',
});
// Seed mock flow from Balaraja agent (F6-2V-DT-8A) to mockDestIp
await Flow.create({
timestamp: new Date(),
agent_uuid: 'F6-2V-DT-8A',
site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e',
src_ip: '192.168.10.50',
dst_ip: mockDestIp,
download: 15000000,
upload: 5000000,
});
// Run the aggregation logic
const devices = await DeviceStat.find({ site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' }).select('ip_address agent_uuid').lean();
const deviceIpToAgent = {};
for (const dev of devices) {
if (dev.ip_address && dev.agent_uuid) {
deviceIpToAgent[dev.ip_address] = dev.agent_uuid;
}
}
const flows = await Flow.find({ site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' }).select('agent_uuid src_ip dst_ip download upload').lean();
const flowMap = {};
for (const flow of flows) {
const srcAgent = flow.agent_uuid;
const dstAgent = deviceIpToAgent[flow.dst_ip];
if (srcAgent && dstAgent && srcAgent !== dstAgent) {
const key = `${srcAgent}->${dstAgent}`;
if (!flowMap[key]) {
flowMap[key] = {
source: srcAgent,
target: dstAgent,
bytes: 0,
flowsCount: 0
};
}
flowMap[key].bytes += ((flow.download || 0) + (flow.upload || 0));
flowMap[key].flowsCount += 1;
}
}
const result = Object.values(flowMap);
assert('Inter-agent flows aggregation should detect flows', result.length > 0);
const detectedFlow = result.find(f => f.source === 'F6-2V-DT-8A' && f.target === '2F-TF-1D-GK');
assert('Mock flow from Balaraja to Cibubur should be detected', !!detectedFlow);
if (detectedFlow) {
assert('Mock flow bytes matches (15MB down + 5MB up = 20MB)', detectedFlow.bytes >= 20000000);
assert('Mock flow connection count is correct', detectedFlow.flowsCount >= 1);
}
// Cleanup mock telemetry
await DeviceStat.deleteOne({ ip_address: mockDestIp });
await Flow.deleteMany({ dst_ip: mockDestIp });
console.log('\n=========================================');
console.log(` RESULT: ${passedCount} / ${testCount} tests passed.`);
console.log('=========================================\n');
await mongoose.disconnect();
} catch (err) {
console.error('TDD Test run error:', err);
process.exit(1);
}
}
runTests();
-118
View File
@@ -1,118 +0,0 @@
// test/architecture_test.js
// TDD: Verifikasi arsitektur 2 container BackOne DPI
const fs = require('fs');
const path = require('path');
const ROOT = path.join(__dirname, '..');
function readFile(relPath) {
return fs.readFileSync(path.join(ROOT, relPath), 'utf8');
}
let passed = 0;
let failed = 0;
function test(name, condition, detail = '') {
if (condition) {
console.log(` ✓ PASS: ${name}`);
passed++;
} else {
console.log(` ✗ FAIL: ${name}${detail ? ' — ' + detail : ''}`);
failed++;
}
}
console.log('\n══════════════════════════════════════════════════════');
console.log(' BackOne DPI — TDD Architecture Verification');
console.log('══════════════════════════════════════════════════════\n');
// ─── TEST GROUP 1: Backend bersih dari SQLite/Netify API ───────────────────
console.log('[GROUP 1] Backend — Isolasi dari SQLite & Netify API');
const serverCode = readFile('backend/server.js');
const dashCode = readFile('backend/routes/dashboard.js') +
readFile('backend/routes/dashboard/helpers.js') +
readFile('backend/routes/dashboard/summary.js') +
readFile('backend/routes/dashboard/apps.js') +
readFile('backend/routes/dashboard/devices.js') +
readFile('backend/routes/dashboard/flows.js') +
readFile('backend/routes/dashboard/threats.js') +
readFile('backend/routes/dashboard/geo.js') +
readFile('backend/routes/dashboard/tls.js') +
readFile('backend/routes/dashboard/telemetry.js') +
readFile('backend/routes/dashboard/events.js') +
readFile('backend/routes/dashboard/agents.js');
const authCode = readFile('backend/routes/auth.js');
test('server.js tidak memanggil ingestionService', !serverCode.includes('ingestionService'));
test('server.js tidak import database.js (SQLite)', !serverCode.includes("require('./database')") && !serverCode.includes("require('../database')"));
test('server.js tidak memanggil startScheduler', !serverCode.includes('startScheduler'));
test('dashboard.js tidak import database.js', !dashCode.includes("require('../database')"));
test('dashboard.js tidak import scheduler.js lama', !dashCode.includes("require('../scheduler')"));
test('dashboard.js tidak memanggil netify.ai API', !dashCode.includes('netify.ai') && !dashCode.includes('fetchTopApps'));
test('auth.js tidak import database.js', !authCode.includes("require('../database')"));
test('auth.js tidak menggunakan better-sqlite3', !authCode.includes('better-sqlite3') && !authCode.includes('getDB()'));
console.log('');
// ─── TEST GROUP 2: Multi-tenant isolation ──────────────────────────────────
console.log('[GROUP 2] Dashboard — Multi-Tenant Agent UUID Isolation');
test('dashboard.js punya getBaseFilter() helper', dashCode.includes('function getBaseFilter'));
test('getBaseFilter menambahkan agent_uuid filter', dashCode.includes('filter.agent_uuid = req.user.agent_uuid'));
test('getBaseFilter menambahkan site_uuid filter', dashCode.includes('filter.site_uuid = req.user.site_uuid') || dashCode.includes('filter.site_uuid ='));
test('/apps pakai getBaseFilter', dashCode.includes("router.get('/apps'") && dashCode.includes('getBaseFilter'));
test('/devices pakai getBaseFilter', dashCode.includes("router.get('/devices'") && dashCode.includes('getBaseFilter'));
test('/flows pakai getBaseFilter', dashCode.includes("router.get('/flows'") && dashCode.includes('getBaseFilter'));
test('/threats pakai getBaseFilter', dashCode.includes("router.get('/threats'") && dashCode.includes('getBaseFilter'));
test('/summary pakai getBaseFilter', dashCode.includes("router.get('/summary'") && dashCode.includes('getBaseFilter'));
test('/agents endpoint hanya untuk SUPER_ADMIN', dashCode.includes("SUPER_ADMIN") && dashCode.includes("router.get('/agents'"));
console.log('');
// ─── TEST GROUP 3: Proxy 2 mode ────────────────────────────────────────────
console.log('[GROUP 3] Proxy — 2 Mode Pengambilan Data');
const schedulerCode = readFile('proxy/scheduler.js');
const collectorCode = readFile('proxy/collector.js');
test('scheduler.js membaca PROXY_COLLECT_MODE env', schedulerCode.includes('PROXY_COLLECT_MODE'));
test('scheduler.js membaca PROXY_AGENT_UUID env', schedulerCode.includes('PROXY_AGENT_UUID'));
test("scheduler.js mendukung mode 'all'", schedulerCode.includes("COLLECT_MODE === 'agent'"));
test('collector.js export collectAllAgents()', collectorCode.includes('collectAllAgents'));
test('collector.js export collectSpecificAgent()', collectorCode.includes('collectSpecificAgent'));
test('collector.js tag data dengan agent_uuid', collectorCode.includes('agent_uuid: agentUuid'));
test('collector.js tag data dengan site_uuid', collectorCode.includes('site_uuid: SITE_UUID') || collectorCode.includes('site_uuid: SITE_UUID') || collectorCode.includes('site_uuid: siteUuid'));
console.log('');
// ─── TEST GROUP 4: Docker Compose 2 Container Groups ─────────────────────
console.log('[GROUP 4] Docker Compose — 2 Container Groups + 2 Networks');
const composeCode = readFile('docker-compose.yml');
test('docker-compose.yml punya service: mongodb', composeCode.includes('mongodb:'));
test('docker-compose.yml punya service: proxy', composeCode.includes('proxy:'));
test('docker-compose.yml punya service: backend', composeCode.includes('backend:'));
test('docker-compose.yml punya service: frontend', composeCode.includes('frontend:'));
test('docker-compose.yml punya network: backone-infra', composeCode.includes('backone-infra'));
test('docker-compose.yml punya network: backone-app', composeCode.includes('backone-app'));
test('proxy connect ke backone-infra (Container 1)', composeCode.includes('backone-infra'));
test('backend connect ke backone-app (Container 2)', composeCode.includes('backone-app'));
test('proxy depends on mongodb', composeCode.includes('service_healthy'));
test('env PROXY_COLLECT_MODE di docker-compose', composeCode.includes('PROXY_COLLECT_MODE'));
test('env PROXY_AGENT_UUID di docker-compose', composeCode.includes('PROXY_AGENT_UUID'));
test('PROXY_URL dikirim ke backend', composeCode.includes('PROXY_URL=http://proxy:4000'));
console.log('');
// ─── TEST GROUP 5: MongoDB Schemas sinkron ────────────────────────────────
console.log('[GROUP 5] MongoDB Schemas — Proxy & Backend Sinkron');
const proxySchema = readFile('proxy/models/Schemas.js');
const backendSchema = readFile('backend/models/Schemas.js');
const sharedFields = ['agent_uuid', 'site_uuid', 'timestamp', 'bandwidth_down', 'bandwidth_up', 'ip_address', 'mac_address', 'flow_id', 'src_ip', 'dst_ip', 'threat_type', 'severity'];
for (const field of sharedFields) {
test(`Field '${field}' ada di kedua schema`, proxySchema.includes(field) && backendSchema.includes(field));
}
console.log('');
// ─── SUMMARY ──────────────────────────────────────────────────────────────
console.log('══════════════════════════════════════════════════════');
console.log(` Results: ${passed} PASSED | ${failed} FAILED`);
console.log('══════════════════════════════════════════════════════\n');
if (failed > 0) process.exit(1);
-98
View File
@@ -1,98 +0,0 @@
// test/branding_unit_test.js
const fs = require('fs');
const path = require('path');
const vm = require('vm');
console.log('=========================================');
console.log(' RUNNING TDD UNIT TEST FOR BRANDING LOGIC');
console.log('=========================================\n');
// 1. Read and transpile src/lib/branding.ts slightly to make it run in Node.js
const brandingCodePath = path.join(__dirname, '../src/lib/branding.ts');
let code = fs.readFileSync(brandingCodePath, 'utf8');
// Strip TypeScript interfaces, return types, parameter types, and export keywords
code = code.replace(/export\s+interface\s+\w+\s*\{[^}]*\}/g, '');
code = code.replace(/:\s*Branding\b/g, '');
code = code.replace(/selectedSiteUuid\?\s*:\s*string/g, 'selectedSiteUuid');
code = code.replace(/export\s+/g, '');
let testCount = 0;
let passedCount = 0;
function assert(label, condition) {
testCount++;
if (condition) {
console.log(` ✓ PASSED: ${label}`);
passedCount++;
} else {
console.error(` ✗ FAILED: ${label}`);
}
}
// Helper to run getSiteBranding with mocked environment
function runGetSiteBranding({ selectedSiteUuid, hostname, search, localStorageVal }) {
const sandbox = {
window: {
location: {
hostname: hostname || 'localhost',
search: search || ''
}
},
localStorage: {
getItem: () => localStorageVal || null
},
console
};
vm.createContext(sandbox);
vm.runInContext(code, sandbox);
return sandbox.getSiteBranding(selectedSiteUuid);
}
try {
// Test Case 1: Default branding (no local storage, localhost)
const brand1 = runGetSiteBranding({
hostname: 'localhost'
});
assert('Default branding should be BackOne', brand1.name === 'BackOne' && brand1.logo === '/backone-logo.png');
// Test Case 2: SIAB site UUID passed explicitly on demoplace.my.id
const brand2 = runGetSiteBranding({
selectedSiteUuid: '6681452d_9cae_4ff4_8ae8_0d504774265e',
hostname: 'demoplace.my.id'
});
assert('SIAB site UUID on demoplace.my.id should return BackOne branding', brand2.name === 'BackOne' && brand2.logo === '/backone-logo.png');
// Test Case 3: SIAB site UUID in localStorage on demoplace.my.id
const brand3 = runGetSiteBranding({
localStorageVal: '6681452d_9cae_4ff4_8ae8_0d504774265e',
hostname: 'demoplace.my.id'
});
assert('SIAB site UUID in localStorage on demoplace.my.id should return BackOne branding', brand3.name === 'BackOne' && brand3.logo === '/backone-logo.png');
// Test Case 4: Nexus site UUID passed explicitly
const brand4 = runGetSiteBranding({
selectedSiteUuid: 'd7902405_0dc2_458b_8584_ed4d24b64f24',
hostname: 'localhost'
});
assert('Nexus site UUID should return Nexus branding', brand4.name === 'Nexus' && brand4.logo === '/nexus-logo.png');
// Test Case 5: Default fallback on demoplace.my.id when no site is selected
const brand5 = runGetSiteBranding({
hostname: 'demoplace.my.id'
});
assert('Fallback on demoplace.my.id should be BackOne branding', brand5.name === 'BackOne' && brand5.logo === '/backone-logo.png');
console.log(`\n=========================================`);
console.log(` RESULT: ${passedCount} / ${testCount} tests passed.`);
console.log(`=========================================\n`);
if (passedCount !== testCount) {
process.exit(1);
} else {
process.exit(0);
}
} catch (err) {
console.error('Test execution failed with error:', err);
process.exit(1);
}
-104
View File
@@ -1,104 +0,0 @@
// test/field_alignment.js
// Check field name alignment between backend and frontend
const fs = require('fs');
const dash = fs.readFileSync('backend/routes/dashboard.js','utf8') +
fs.readFileSync('backend/routes/dashboard/helpers.js','utf8') +
fs.readFileSync('backend/routes/dashboard/summary.js','utf8') +
fs.readFileSync('backend/routes/dashboard/apps.js','utf8') +
fs.readFileSync('backend/routes/dashboard/devices.js','utf8') +
fs.readFileSync('backend/routes/dashboard/flows.js','utf8') +
fs.readFileSync('backend/routes/dashboard/threats.js','utf8') +
fs.readFileSync('backend/routes/dashboard/geo.js','utf8') +
fs.readFileSync('backend/routes/dashboard/tls.js','utf8') +
fs.readFileSync('backend/routes/dashboard/telemetry.js','utf8') +
fs.readFileSync('backend/routes/dashboard/events.js','utf8');
const api = fs.readFileSync('src/lib/api.ts','utf8') +
fs.readFileSync('src/lib/api-types.ts','utf8');
console.log('=== Field Name Alignment: Backend ↔ Frontend ===\n');
function check(label, backendHas, frontendExpects, mismatchDesc = '') {
if (backendHas && frontendExpects) {
console.log(` ✓ PASS: ${label} is aligned`);
} else if (backendHas && !frontendExpects) {
console.log(` ⚠ WARNING: Backend defines ${label} but Frontend doesn't expect it`);
} else if (!backendHas && frontendExpects) {
console.log(` ✗ FAIL: ${label} is missing in backend routing!`);
if (mismatchDesc) console.log(` → ${mismatchDesc}`);
}
}
// /protocols
console.log('[/protocols]');
check(
'protocol_label',
dash.includes('protocol_label'),
api.includes('protocol_label'),
'Backend doesn\'t return protocol_label to frontend'
);
console.log('');
// /timeline
console.log('[/timeline]');
check(
'fetched_at',
dash.includes('fetched_at'),
api.includes('fetched_at'),
'Backend sends timestamp, frontend reads fetched_at'
);
console.log('');
// /countries
console.log('[/countries]');
check(
'country_name',
dash.includes('country_name'),
api.includes('country_name'),
'Backend does not return country_name'
);
check(
'country_code',
dash.includes('country_code'),
api.includes('country_code'),
'Backend does not return country_code'
);
console.log('');
// /dns
console.log('[/dns]');
check(
'domain',
dash.includes('domain'),
api.includes('domain'),
'Backend does not map domain field'
);
console.log('');
// /summary
console.log('[/summary]');
check('total_devices', dash.includes('total_devices'), api.includes('total_devices'));
check('bandwidth_down', dash.includes('bandwidth_down'), api.includes('bandwidth_down'));
check('download_speed', dash.includes('download_speed'), api.includes('download_speed'));
console.log('');
// /apps
console.log('[/apps]');
check('app_label', dash.includes('app_label'), api.includes('app_label'));
console.log('');
// /flows
console.log('[/flows]');
check('src_ip', dash.includes('src_ip'), api.includes('src_ip'));
check('dst_port', dash.includes('dst_port'), api.includes('dst_port'));
console.log('');
// app-categories
console.log('[/app-categories]');
check(
'category_label',
dash.includes('category_label'),
api.includes('category_label'),
'Backend sends label, frontend expects category_label'
);
console.log('');
-28
View File
@@ -1,28 +0,0 @@
// test/middleware_verification_test.js
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const ROOT = path.join(__dirname, '..');
console.log('=== Running TDD Middleware Verification Test ===');
try {
// 1. Verify src/middleware.ts exists
const middlewarePath = path.join(ROOT, 'src', 'middleware.ts');
const exists = fs.existsSync(middlewarePath);
assert.ok(exists, 'src/middleware.ts must exist');
console.log('✓ src/middleware.ts exists');
// 2. Verify it exports 'middleware' function
const content = fs.readFileSync(middlewarePath, 'utf8');
assert.ok(content.includes('export function middleware'), 'src/middleware.ts must export function middleware');
assert.ok(!content.includes('export function proxy'), 'src/middleware.ts must NOT export function proxy');
console.log('✓ src/middleware.ts exports function middleware correctly');
console.log('=== ALL TESTS PASSED ===');
process.exit(0);
} catch (err) {
console.error('✗ TEST FAILED:', err.message);
process.exit(1);
}
-64
View File
@@ -1,64 +0,0 @@
// test/multipart_proxy_test.js
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const ROOT = path.join(__dirname, '..');
console.log('=========================================');
console.log(' RUNNING TDD TESTS FOR MULTIPART PROXIES');
console.log('=========================================\n');
let testCount = 0;
let passedCount = 0;
function runAssert(label, condition) {
testCount++;
if (condition) {
console.log(` ✓ PASSED: ${label}`);
passedCount++;
} else {
console.error(` ✗ FAILED: ${label}`);
}
}
try {
// Test Case 1: Cek keberadaan file src/app/api/auth/admin/create-external-user/route.ts
const createRoutePath = path.join(ROOT, 'src', 'app', 'api', 'auth', 'admin', 'create-external-user', 'route.ts');
const createExists = fs.existsSync(createRoutePath);
runAssert('create-external-user/route.ts should exist', createExists);
if (createExists) {
const content = fs.readFileSync(createRoutePath, 'utf8');
runAssert('create-external-user/route.ts should export POST handler', content.includes('export async function POST'));
runAssert('create-external-user/route.ts should read req.json(), req.body or req.formData()', content.includes('req.json()') || content.includes('req.body') || content.includes('req.formData()'));
runAssert('create-external-user/route.ts should forward auth cookie', content.includes('Cookie') || content.includes('cookie'));
runAssert('create-external-user/route.ts should use NEXT_PUBLIC_API_URL or port 3011', content.includes('NEXT_PUBLIC_API_URL') || content.includes('3011'));
}
// Test Case 2: Cek keberadaan file src/app/api/auth/admin/update-agent-user/route.ts
const updateRoutePath = path.join(ROOT, 'src', 'app', 'api', 'auth', 'admin', 'update-agent-user', 'route.ts');
const updateExists = fs.existsSync(updateRoutePath);
runAssert('update-agent-user/route.ts should exist', updateExists);
if (updateExists) {
const content = fs.readFileSync(updateRoutePath, 'utf8');
runAssert('update-agent-user/route.ts should export POST handler', content.includes('export async function POST'));
runAssert('update-agent-user/route.ts should read req.json(), req.body or req.formData()', content.includes('req.json()') || content.includes('req.body') || content.includes('req.formData()'));
runAssert('update-agent-user/route.ts should forward auth cookie', content.includes('Cookie') || content.includes('cookie'));
runAssert('update-agent-user/route.ts should use NEXT_PUBLIC_API_URL or port 3011', content.includes('NEXT_PUBLIC_API_URL') || content.includes('3011'));
}
console.log(`\n=========================================`);
console.log(` RESULT: ${passedCount} / ${testCount} tests passed.`);
console.log(`=========================================\n`);
if (passedCount !== testCount) {
process.exit(1);
} else {
process.exit(0);
}
} catch (err) {
console.error('Test execution failed with error:', err);
process.exit(1);
}
-149
View File
@@ -1,149 +0,0 @@
// test/multitenant_branding_test.js
const mongoose = require('../backend/node_modules/mongoose');
const path = require('path');
// Load environment variables
require('dotenv').config({ path: path.join(__dirname, '../.env.local') });
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://127.0.0.1:27017/backone_dpi';
const User = require('../backend/models/User');
const { TenantConfig } = require('../backend/models/Schemas');
let testCount = 0;
let passedCount = 0;
function assert(label, condition) {
testCount++;
if (condition) {
console.log(` ✓ PASSED: ${label}`);
passedCount++;
} else {
console.error(` ✗ FAILED: ${label}`);
}
}
async function runTests() {
console.log('\n=========================================');
console.log(' RUNNING TDD TESTS FOR MULTI-TENANCY & BRANDING');
console.log('=========================================\n');
try {
// 1. Connect to DB
await mongoose.connect(MONGODB_URI);
console.log('✓ Connected to MongoDB');
// Ensure at least one summary document exists for both SIAB and Nexus
const dbConnection = mongoose.connection.db;
const hasSiabSummary = await dbConnection.collection('summaries').findOne({ site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' });
if (!hasSiabSummary) {
await dbConnection.collection('summaries').insertOne({
timestamp: new Date(),
agent_uuid: 'mock_siab_agent_uuid',
site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e',
bandwidth_down: 100,
bandwidth_up: 50,
active_flows: 10
});
}
const hasNexusSummary = await dbConnection.collection('summaries').findOne({ site_uuid: 'd7902405_0dc2_458b_8584_ed4d24b64f24' });
if (!hasNexusSummary) {
await dbConnection.collection('summaries').insertOne({
timestamp: new Date(),
agent_uuid: 'mock_nexus_agent_uuid',
site_uuid: 'd7902405_0dc2_458b_8584_ed4d24b64f24',
bandwidth_down: 100,
bandwidth_up: 50,
active_flows: 10
});
}
// 2. Validate User Accounts Seeding
const adminUser = await User.findOne({ username: 'admin' });
assert('User "admin" should exist', !!adminUser);
if (adminUser) {
assert('User "admin" should have SUPER_ADMIN role', adminUser.role === 'SUPER_ADMIN');
}
const siabUser = await User.findOne({ username: 'siab' });
assert('User "siab" should exist', !!siabUser);
if (siabUser) {
assert('User "siab" should have TENANT_ADMIN role', siabUser.role === 'TENANT_ADMIN');
assert('User "siab" should belong to SIAB site_uuid', siabUser.site_uuid === '6681452d_9cae_4ff4_8ae8_0d504774265e');
}
const nexusUser = await User.findOne({ username: 'nexus' });
assert('User "nexus" should exist', !!nexusUser);
if (nexusUser) {
assert('User "nexus" should have TENANT_ADMIN role', nexusUser.role === 'TENANT_ADMIN');
assert('User "nexus" should belong to Nexus site_uuid', nexusUser.site_uuid === 'd7902405_0dc2_458b_8584_ed4d24b64f24');
}
// 3. Validate TenantConfig configurations
const backoneConfig = await TenantConfig.findOne({ site_uuid: 'default' });
assert('Default branding config should exist', !!backoneConfig);
if (backoneConfig) {
assert('Default brand_name should be BackOne', backoneConfig.brand_name === 'BackOne');
assert('Default brand_logo should be /backone-logo.png', backoneConfig.brand_logo === '/backone-logo.png');
}
const siabConfig = await TenantConfig.findOne({ site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' });
assert('SIAB branding config should exist', !!siabConfig);
if (siabConfig) {
assert('SIAB brand_name should be SIAB', siabConfig.brand_name === 'SIAB');
assert('SIAB brand_logo should be /siab-logo.png', siabConfig.brand_logo === '/siab-logo.png');
}
const nexusConfig = await TenantConfig.findOne({ site_uuid: 'd7902405_0dc2_458b_8584_ed4d24b64f24' });
assert('Nexus branding config should exist', !!nexusConfig);
if (nexusConfig) {
assert('Nexus brand_name should be Nexus', nexusConfig.brand_name === 'Nexus');
assert('Nexus brand_logo should be /nexus-logo.png', nexusConfig.brand_logo === '/nexus-logo.png');
}
// 4. Validate Agent listing isolation per site_uuid (summaries collection)
const db = mongoose.connection.db;
const siabAgents = await db.collection('summaries').distinct('agent_uuid', { site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e' });
const nexusAgents = await db.collection('summaries').distinct('agent_uuid', { site_uuid: 'd7902405_0dc2_458b_8584_ed4d24b64f24' });
assert('SIAB agents count should be greater than 0', siabAgents.length > 0);
assert('Nexus agents count should be greater than 0', nexusAgents.length > 0);
// Check that agents do not overlap
const overlap = siabAgents.filter(uuid => nexusAgents.includes(uuid));
assert('SIAB and Nexus agent lists should have 0 overlapping agents', overlap.length === 0);
// 5. Validate User creation isolation (created_by query)
const testAdminCreated = await User.find({ created_by: 'admin' });
const testNexusCreated = await User.find({ created_by: 'nexus' });
assert('Superadmin users should return a queryable list of registered accounts', Array.isArray(testAdminCreated));
assert('Nexus admin users should return a queryable list of registered accounts', Array.isArray(testNexusCreated));
// Verify tenant-admin custom query filter returns AGENT_VIEWER accounts for their site
const mockTenantUser = { role: 'TENANT_ADMIN', site_uuid: 'd7902405_0dc2_458b_8584_ed4d24b64f24', username: 'nexus' };
const query = {
$or: [
{ role: 'AGENT_VIEWER', site_uuid: mockTenantUser.site_uuid },
{ created_by: mockTenantUser.username }
]
};
const queryResults = await User.find(query);
assert('Tenant user list query should execute successfully', Array.isArray(queryResults));
console.log(`\n=========================================`);
console.log(` RESULT: ${passedCount} / ${testCount} tests passed.`);
console.log(`=========================================\n`);
if (passedCount !== testCount) {
process.exit(1);
} else {
process.exit(0);
}
} catch (err) {
console.error('Test execution failed with error:', err);
process.exit(1);
}
}
runTests();
-29
View File
@@ -1,29 +0,0 @@
// test/sftp_manifest_test.js
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const ROOT = path.join(__dirname, '..');
console.log('=== Running TDD SFTP Manifest Verification Test ===');
try {
const deployScriptPath = path.join(ROOT, 'scripts', 'deploy-sftp.js');
const exists = fs.existsSync(deployScriptPath);
assert.ok(exists, 'scripts/deploy-sftp.js must exist');
const content = fs.readFileSync(deployScriptPath, 'utf8');
// Verify .next/static is in the upload manifest
assert.ok(
content.includes("local: '.next/static'") || content.includes('local: ".next/static"'),
'scripts/deploy-sftp.js must include local: \'.next/static\' in UPLOAD_MANIFEST'
);
console.log('✓ scripts/deploy-sftp.js includes .next/static in UPLOAD_MANIFEST');
console.log('=== ALL TESTS PASSED ===');
process.exit(0);
} catch (err) {
console.error('✗ TEST FAILED:', err.message);
process.exit(1);
}
-118
View File
@@ -1,118 +0,0 @@
// test/sidebar_styling_test.js
const fs = require('fs');
const path = require('path');
const sidebarPath = path.join(__dirname, '../src/components/layout/Sidebar.tsx');
const siteSelectorPath = path.join(__dirname, '../src/components/layout/SidebarSiteSelector.tsx');
const timeSelectorPath = path.join(__dirname, '../src/components/layout/SidebarTimeSelector.tsx');
const globalsCssPath = path.join(__dirname, '../src/app/globals.css');
const agentsPagePath = path.join(__dirname, '../src/app/(dashboard)/agents/page.tsx');
let testCount = 0;
let passedCount = 0;
function assert(label, condition) {
testCount++;
if (condition) {
console.log(` ✓ PASSED: ${label}`);
passedCount++;
} else {
console.error(` ✗ FAILED: ${label}`);
}
}
function runTests() {
console.log('\n=========================================');
console.log(' RUNNING TDD TESTS FOR SIDEBAR & PAGE STYLING');
console.log('=========================================\n');
try {
const sidebarContent = fs.readFileSync(sidebarPath, 'utf8');
assert(
'Sidebar.tsx should use Times New Roman font family stack',
sidebarContent.includes("'Times New Roman', Times, serif")
);
assert(
'Sidebar.tsx link items should be compact (text-xs or text-[13px])',
sidebarContent.includes('text-xs') || sidebarContent.includes('text-[13px]')
);
} catch (err) {
assert(`Sidebar.tsx read error: ${err.message}`, false);
}
try {
const siteSelectorContent = fs.readFileSync(siteSelectorPath, 'utf8');
assert(
'SidebarSiteSelector.tsx should use Times New Roman font family stack',
siteSelectorContent.includes("'Times New Roman', Times, serif")
);
assert(
'SidebarSiteSelector.tsx label should use correct size (text-[9.5px] to text-[10.5px])',
siteSelectorContent.includes('text-[10px]') || siteSelectorContent.includes('text-[10.5px]') || siteSelectorContent.includes('text-[9.5px]')
);
assert(
'SidebarSiteSelector.tsx value should use correct size (text-xs or text-sm)',
siteSelectorContent.includes('text-xs') || siteSelectorContent.includes('text-sm') || siteSelectorContent.includes('text-[13.5px]')
);
} catch (err) {
assert(`SidebarSiteSelector.tsx read error: ${err.message}`, false);
}
try {
const timeSelectorContent = fs.readFileSync(timeSelectorPath, 'utf8');
assert(
'SidebarTimeSelector.tsx should use Times New Roman font family stack',
timeSelectorContent.includes("'Times New Roman', Times, serif")
);
assert(
'SidebarTimeSelector.tsx label should use correct size (text-[9.5px] to text-[10.5px])',
timeSelectorContent.includes('text-[10px]') || timeSelectorContent.includes('text-[10.5px]') || timeSelectorContent.includes('text-[9.5px]')
);
assert(
'SidebarTimeSelector.tsx value should use correct size (text-xs or text-sm)',
timeSelectorContent.includes('text-xs') || timeSelectorContent.includes('text-sm') || timeSelectorContent.includes('text-[13.5px]')
);
} catch (err) {
assert(`SidebarTimeSelector.tsx read error: ${err.message}`, false);
}
try {
const globalsCssContent = fs.readFileSync(globalsCssPath, 'utf8');
assert(
'globals.css body rule should enforce Times New Roman font-family',
globalsCssContent.includes("font-family: 'Times New Roman', Times, serif;")
);
} catch (err) {
assert(`globals.css read error: ${err.message}`, false);
}
try {
const agentsPageContent = fs.readFileSync(agentsPagePath, 'utf8');
assert(
'agents/page.tsx should display "Agents Inventory" title',
agentsPageContent.includes('Agents Inventory')
);
assert(
'agents/page.tsx should display subtitle description',
agentsPageContent.includes('Managed DPI probes, remote collectors, and probe infrastructure.')
);
assert(
'agents/page.tsx header should not render the Server icon',
!agentsPageContent.includes('<Server className=') && !agentsPageContent.includes('<Server ')
);
} catch (err) {
assert(`agents/page.tsx read error: ${err.message}`, false);
}
console.log('\n=========================================');
console.log(` RESULT: ${passedCount}/${testCount} tests passed`);
console.log('=========================================\n');
if (passedCount !== testCount) {
process.exit(1);
} else {
process.exit(0);
}
}
runTests();
-197
View File
@@ -1,197 +0,0 @@
// test/sync_test.js
// TDD Integration Test: Verifikasi sinkronisasi 100% file antara Localhost dan Domain
'use strict';
const { Client } = require('ssh2');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
// Load environment variables if available
try {
require('dotenv').config({ path: path.join(__dirname, '../.env.local') });
} catch (e) {}
const SSH = {
host: '103.185.47.52',
port: 2222,
username: 'adminbackend',
password: 'htEo7x6LsBQiEHHH',
readyTimeout: 60000
};
const REMOTE_ROOT = '/home/adminbackend/web/dev.demoplace.my.id/public_html';
const LOCAL_ROOT = path.join(__dirname, '..');
let testCount = 0;
let passedCount = 0;
function assert(label, condition) {
testCount++;
if (condition) {
console.log(` ✓ PASSED: ${label}`);
passedCount++;
} else {
console.error(` ✗ FAILED: ${label}`);
}
}
function getMD5(filePath) {
try {
const data = fs.readFileSync(filePath);
return crypto.createHash('md5').update(data).digest('hex');
} catch (e) {
return null;
}
}
function getFilesLocal(dir, files = []) {
const list = fs.readdirSync(dir);
for (const item of list) {
const fullPath = path.join(dir, item);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
if (item !== 'node_modules' && item !== '.next' && item !== '.git') {
getFilesLocal(fullPath, files);
}
} else {
files.push(path.relative(LOCAL_ROOT, fullPath).replace(/\\/g, '/'));
}
}
return files;
}
const remoteScript = `
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const root = '/home/adminbackend/web/dev.demoplace.my.id/public_html';
function getMD5(filePath) {
try {
const data = fs.readFileSync(filePath);
return crypto.createHash('md5').update(data).digest('hex');
} catch (e) {
return null;
}
}
function getFilesRemote(dir, files = {}) {
try {
const list = fs.readdirSync(dir);
for (const item of list) {
const fullPath = path.join(dir, item);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
if (item !== 'node_modules' && item !== '.next' && item !== '.git') {
getFilesRemote(fullPath, files);
}
} else {
const rel = path.relative(root, fullPath);
files[rel] = { md5: getMD5(fullPath), size: stat.size };
}
}
} catch(e) {}
return files;
}
const filesMap = {};
getFilesRemote(path.join(root, 'src'), filesMap);
getFilesRemote(path.join(root, 'public'), filesMap);
getFilesRemote(path.join(root, 'backend'), filesMap);
getFilesRemote(path.join(root, 'proxy'), filesMap);
const rootConfigs = ['package.json', 'tsconfig.json', 'next.config.ts', '.env.production'];
for (const f of rootConfigs) {
const full = path.join(root, f);
if (fs.existsSync(full)) {
const stat = fs.statSync(full);
filesMap[f] = { md5: getMD5(full), size: stat.size };
}
}
console.log(JSON.stringify(filesMap));
`;
async function runTests() {
console.log('\n=========================================');
console.log(' RUNNING TDD SYNC COMPARISON TESTS');
console.log('=========================================\n');
let remoteFiles = {};
try {
const conn = new Client();
const remoteFilesStr = await new Promise((resolve, reject) => {
conn.on('ready', () => {
const b64 = Buffer.from(remoteScript).toString('base64');
conn.exec(`echo "${b64}" | base64 -d | node`, (err, stream) => {
if (err) return reject(err);
let out = '';
let errOut = '';
stream.on('data', d => out += d);
stream.stderr.on('data', d => errOut += d);
stream.on('close', () => {
conn.end();
if (errOut.trim()) {
reject(new Error(errOut));
} else {
resolve(out);
}
});
});
}).on('error', reject).connect(SSH);
});
remoteFiles = JSON.parse(remoteFilesStr);
console.log('✓ Connected to remote server and retrieved remote file list.');
} catch (err) {
console.error('✗ Failed to connect to remote server:', err.message);
process.exit(1);
}
// Get local files
const localFiles = {};
const pathsToCheck = ['src', 'public', 'backend', 'proxy'];
for (const p of pathsToCheck) {
const full = path.join(LOCAL_ROOT, p);
if (fs.existsSync(full)) {
const files = getFilesLocal(full);
for (const f of files) {
const localPath = path.join(LOCAL_ROOT, f);
localFiles[f] = { md5: getMD5(localPath) };
}
}
}
const rootConfigs = ['package.json', 'tsconfig.json', 'next.config.ts', '.env.production'];
for (const f of rootConfigs) {
const full = path.join(LOCAL_ROOT, f);
if (fs.existsSync(full)) {
localFiles[f] = { md5: getMD5(full) };
}
}
// Perform assertions
for (const [relPath, info] of Object.entries(remoteFiles)) {
const localInfo = localFiles[relPath];
assert(`File "${relPath}" should exist locally`, !!localInfo);
if (localInfo) {
assert(`File "${relPath}" content should match remote exactly`, localInfo.md5 === info.md5);
}
}
console.log(`\n=========================================`);
console.log(` RESULT: ${passedCount} / ${testCount} tests passed.`);
console.log(`=========================================\n`);
if (passedCount !== testCount) {
process.exit(1);
} else {
process.exit(0);
}
}
runTests().catch(e => {
console.error('[FATAL]', e.message);
process.exit(1);
});
-28
View File
@@ -1,28 +0,0 @@
const axios = require('axios');
const BASE_URL = 'https://api0.dev.backone.cloud/api/v1';
const { backoneFetch } = require('./proxy/backoneClientCore');
async function test() {
const agentUuid = 'F6-2V-DT-8A';
console.log(`Fetching flows for Agent UUID: ${agentUuid}...`);
const flows = await backoneFetch('/data/flows', { settings_limit: 200 }, agentUuid);
const ips = flows ? flows.map(f => f.local_ip?.address).filter(Boolean) : [];
const ips10_6 = ips.filter(ip => ip.startsWith('10.6'));
const ips192 = ips.filter(ip => ip.startsWith('192.168'));
const ips10_1 = ips.filter(ip => ip.startsWith('10.1.'));
console.log('\n--- Hasil Test untuk Agen', agentUuid, '---');
console.log(`Total IPs didapat: ${ips.length}`);
console.log(`Jumlah IP Balaraja (10.6.x.x): ${ips10_6.length}`);
if (ips10_6.length > 0) console.log('Contoh 10.6.x.x:', ips10_6.slice(0, 5));
console.log(`\nJumlah IP Kantor/Lainnya (192.168.x.x): ${ips192.length}`);
if (ips192.length > 0) console.log('Contoh 192.168.x.x:', ips192.slice(0, 5));
console.log(`\nJumlah IP Lainnya (10.1.x.x): ${ips10_1.length}`);
if (ips10_1.length > 0) console.log('Contoh 10.1.x.x:', ips10_1.slice(0, 5));
}
test();
-18
View File
@@ -1,18 +0,0 @@
const mongoose = require('mongoose');
mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0').then(async () => {
const db = mongoose.connection.db;
const raw = await db.collection('countrystats').aggregate([
{ $group: {
_id: '$country_name',
download: { $sum: '$download' },
upload: { $sum: '$upload' },
flow_count: { $sum: { $ifNull: ['$flows', 1] } },
country_code: { $first: '$country_name' }
}},
{ $sort: { download: -1 } },
{ $limit: 200 }
]).toArray();
console.log(raw.length, 'countries returned');
console.log(raw.slice(0, 10));
mongoose.disconnect();
});
-20
View File
@@ -1,20 +0,0 @@
const mongoose = require('mongoose');
mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0').then(async () => {
const db = mongoose.connection.db;
const raw = await db.collection('countrystats').aggregate([
{ $group: {
_id: '$country_name',
download: { $sum: '$download' },
upload: { $sum: '$upload' },
flow_count: { $sum: { $ifNull: ['$flows', 1] } },
country_code: { $first: '$country_name' }
}},
{ $sort: { download: -1 } },
{ $limit: 200 }
]).toArray();
const data = raw.filter(r => r.country_code && r.country_code !== 'Unknown' && r.country_code.length === 2);
const dataWithBW = data.filter(r => r.download > 0 || r.upload > 0);
console.log('Total valid countries:', data.length);
console.log('Countries with > 0 bandwidth:', dataWithBW.length);
mongoose.disconnect();
});
-30
View File
@@ -1,30 +0,0 @@
const mongoose = require('mongoose');
mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0').then(async () => {
const db = mongoose.connection.db;
const raw = await db.collection('countrystats').aggregate([
{ $match: { agent_uuid: 'F6-2V-DT-8A' } },
{ $group: {
_id: '$country_name',
download: { $sum: '$download' },
upload: { $sum: '$upload' }
}},
{ $sort: { download: -1 } },
{ $limit: 200 }
]).toArray();
const valid = raw.filter(r => r.download > 0 || r.upload > 0);
console.log(valid.length, 'valid countries for Kantor in CountryStat');
const flows = await db.collection('flows').aggregate([
{ $match: { agent_uuid: 'F6-2V-DT-8A', country_name: { $ne: null } } },
{ $group: {
_id: '$country_name',
download: { $sum: '$download' },
upload: { $sum: '$upload' }
}},
{ $sort: { download: -1 } },
{ $limit: 200 }
]).toArray();
const validFlows = flows.filter(r => r.download > 0 || r.upload > 0);
console.log(validFlows.length, 'valid countries for Kantor in Flow');
mongoose.disconnect();
});
-16
View File
@@ -1,16 +0,0 @@
const mongoose = require('mongoose');
mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0').then(async () => {
const db = mongoose.connection.db;
const now = new Date();
const filter = { timestamp: { $gte: new Date(now.getTime() - 24 * 3600000) } };
const raw = await db.collection('countrystats').aggregate([
{ $match: filter },
{ $group: {
_id: '$country_name',
download: { $sum: '$download' },
upload: { $sum: '$upload' }
}}
]).toArray();
console.log(raw.length, 'countries in last 24h');
mongoose.disconnect();
});
-11
View File
@@ -1,11 +0,0 @@
const mongoose = require('mongoose');
mongoose.connect('mongodb://backone_inspect:backone_inspect@mongodb.prod.proit.id:27017/backone_inspect_0').then(async () => {
const db = mongoose.connection.db;
const flows = await db.collection('flows').aggregate([
{ $group: { _id: '$agent_uuid', src_ips: { $addToSet: '$src_ip' } } }
]).toArray();
flows.forEach(f => {
console.log('Agent:', f._id, 'IPs:', f.src_ips.slice(0, 10).join(', '));
});
mongoose.disconnect();
});