style(sidebar): match active item highlight and header buttons 100% with demoplace.my.id
This commit is contained in:
1 parent
7f133a287b
commit
960322e30a
49 files changed
+3226
-1503
No files matched your search
@@ -0,0 +1,61 @@
|
||||
const https = require('https');
|
||||
|
||||
const PAGES = [
|
||||
'/',
|
||||
'/network-infrastructure',
|
||||
'/agents',
|
||||
'/devices',
|
||||
'/flows',
|
||||
'/apps',
|
||||
'/network-intelligence',
|
||||
'/dns',
|
||||
'/geography',
|
||||
'/dpi-analytics',
|
||||
'/lookup',
|
||||
'/intelligence',
|
||||
'/threats',
|
||||
'/events',
|
||||
'/security-audit',
|
||||
'/help'
|
||||
];
|
||||
|
||||
function fetchPage(route) {
|
||||
return new Promise((resolve) => {
|
||||
https.get(`https://demoplace.my.id${route}`, (res) => {
|
||||
let data = '';
|
||||
res.on('data', chunk => data += chunk);
|
||||
res.on('end', () => {
|
||||
const titleMatch = data.match(/<title>(.*?)<\/title>/i);
|
||||
const descMatch = data.match(/<meta name="description" content="(.*?)"/i);
|
||||
const title = titleMatch ? titleMatch[1] : 'N/A';
|
||||
const desc = descMatch ? descMatch[1] : 'N/A';
|
||||
|
||||
// Find logo references
|
||||
const logos = [];
|
||||
const logoRegex = /src="([^"]*(?:logo|icon)[^"]*)"/gi;
|
||||
let match;
|
||||
while ((match = logoRegex.exec(data)) !== null) {
|
||||
if (!logos.includes(match[1])) logos.push(match[1]);
|
||||
}
|
||||
|
||||
resolve({ route, statusCode: res.statusCode, title, desc, logos });
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
resolve({ route, error: err.message });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('=== AUDITING DEMOPLACE.MY.ID PAGES ===\n');
|
||||
for (const page of PAGES) {
|
||||
const res = await fetchPage(page);
|
||||
console.log(`Route: ${res.route}`);
|
||||
console.log(` Title : ${res.title}`);
|
||||
console.log(` Description : ${res.desc}`);
|
||||
console.log(` Logos/Icons : ${res.logos ? res.logos.join(', ') : 'None'}`);
|
||||
console.log('---');
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,57 @@
|
||||
const { Client } = require('ssh2');
|
||||
const fs = require('fs');
|
||||
|
||||
const remoteScript = `
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const root = '/home/adminbackend/web/demoplace.my.id/public_html';
|
||||
|
||||
console.log('=== 1. LOGOS & IMAGES IN PUBLIC ===');
|
||||
try {
|
||||
const publicFiles = fs.readdirSync(path.join(root, 'public'));
|
||||
console.log('Files in public/:', publicFiles);
|
||||
} catch(e) { console.log('Err:', e.message); }
|
||||
|
||||
console.log('\\n=== 2. AUDITING NAVIGATION GROUPS IN STANDALONE CHUNKS ===');
|
||||
const chunksDir = path.join(root, '.next/standalone/.next/server/chunks');
|
||||
if (fs.existsSync(chunksDir)) {
|
||||
const files = fs.readdirSync(chunksDir);
|
||||
files.forEach(f => {
|
||||
if (!f.endsWith('.js')) return;
|
||||
const content = fs.readFileSync(path.join(chunksDir, f), 'utf8');
|
||||
if (content.includes('Overview Dashboard') || content.includes('Network Topology')) {
|
||||
console.log('Chunk File:', f);
|
||||
const match = content.match(/title:\"OVERVIEW\".*?title:\"SECURITY & ALERTS\".*?\]/);
|
||||
if (match) {
|
||||
console.log('NAV MATCH:', match[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log('\\n=== 3. APP ROUTE DIRECTORIES ===');
|
||||
try {
|
||||
const appDir = path.join(root, '.next/standalone/.next/server/app/(dashboard)');
|
||||
if (fs.existsSync(appDir)) {
|
||||
console.log('Dashboard routes in .next/standalone:', fs.readdirSync(appDir));
|
||||
}
|
||||
} catch(e) { console.log('Err app dir:', e.message); }
|
||||
`;
|
||||
|
||||
const conn = new Client();
|
||||
conn.on('ready', () => {
|
||||
conn.exec(`node -e ${JSON.stringify(remoteScript)}`, (err, stream) => {
|
||||
let out = '';
|
||||
stream.on('data', d => out += d);
|
||||
stream.on('close', () => {
|
||||
console.log(out);
|
||||
conn.end();
|
||||
});
|
||||
});
|
||||
}).connect({
|
||||
host: '103.185.47.52',
|
||||
port: 2222,
|
||||
username: 'adminbackend',
|
||||
password: 'htEo7x6LsBQiEHHH'
|
||||
});
|
||||
@@ -11,7 +11,7 @@ const config = {
|
||||
password: 'htEo7x6LsBQiEHHH'
|
||||
};
|
||||
|
||||
const DEPLOY_DIR = 'web/demoplace.my.id/public_html';
|
||||
const DEPLOY_DIR = 'backone-production';
|
||||
|
||||
async function createZip() {
|
||||
console.log("Packaging application...");
|
||||
@@ -30,15 +30,11 @@ async function createZip() {
|
||||
// Add static assets (Next.js standalone requires these copied over)
|
||||
archive.directory(path.join(__dirname, '../.next/static'), '.next/static');
|
||||
archive.directory(path.join(__dirname, '../public'), 'public');
|
||||
archive.directory(path.join(__dirname, '../public'), false);
|
||||
|
||||
// Add backend and proxy
|
||||
archive.directory(path.join(__dirname, '../backend'), 'backend');
|
||||
archive.directory(path.join(__dirname, '../proxy'), 'proxy');
|
||||
|
||||
// Add PM2 ecosystem config
|
||||
archive.file(path.join(__dirname, '../ecosystem.config.js'), { name: 'ecosystem.config.js' });
|
||||
|
||||
// Add production env
|
||||
archive.file(path.join(__dirname, '../.env.production'), { name: '.env.production' });
|
||||
|
||||
@@ -85,24 +81,26 @@ async function deploy() {
|
||||
await sftp.put(zipPath, `${targetDir}/deploy.zip`);
|
||||
|
||||
console.log("Extracting package on server...");
|
||||
await runSSH(`cd ${targetDir} && rm -rf .next && unzip -o deploy.zip && rm deploy.zip`);
|
||||
await runSSH(`cd ${targetDir} && unzip -o deploy.zip && rm deploy.zip`);
|
||||
|
||||
console.log("Creating symlink for static files...");
|
||||
await runSSH(`cd ${targetDir} && rm -rf _next && ln -s .next _next`);
|
||||
|
||||
console.log("Installing production dependencies for root, backend & proxy...");
|
||||
await runSSH(`. ~/.nvm/nvm.sh && nvm use 20 && cd ${targetDir} && npm install --production`);
|
||||
await runSSH(`. ~/.nvm/nvm.sh && nvm use 20 && cd ${targetDir}/backend && npm install --production`);
|
||||
await runSSH(`. ~/.nvm/nvm.sh && nvm use 20 && cd ${targetDir}/proxy && npm install --production`);
|
||||
console.log("Installing production dependencies for backend & proxy...");
|
||||
await runSSH(`cd ${targetDir}/backend && npm install --production`);
|
||||
await runSSH(`cd ${targetDir}/proxy && npm install --production`);
|
||||
|
||||
console.log("Configuring PM2...");
|
||||
// PM2 ecosystem is now packaged in deploy.zip directly, no need to generate via bash echo.
|
||||
|
||||
// Create ecosystem file for PM2
|
||||
const ecosystem = `
|
||||
module.exports = {
|
||||
apps: [
|
||||
{ name: 'backone-proxy', script: './proxy/index.js', env_file: '.env.production' },
|
||||
{ name: 'backone-backend', script: './backend/server.js', env_file: '.env.production' },
|
||||
{ name: 'backone-frontend', script: 'server.js', env_file: '.env.production' }
|
||||
]
|
||||
};`;
|
||||
await runSSH(`cd ${targetDir} && echo "${ecosystem.replace(/\n/g, '\\n')}" > ecosystem.config.js`);
|
||||
|
||||
console.log("Restarting PM2 processes...");
|
||||
// Clean delete old PM2 processes if they exist to apply new paths, then start fresh
|
||||
await runSSH(`. ~/.nvm/nvm.sh && nvm use 20 && npx pm2 delete backone-frontend backone-backend backone-proxy || true`);
|
||||
const pm2Result = await runSSH(`. ~/.nvm/nvm.sh && nvm use 20 && cd ${targetDir} && npx pm2 start ecosystem.config.js`);
|
||||
const pm2Result = await runSSH(`cd ${targetDir} && pm2 start ecosystem.config.js || pm2 restart ecosystem.config.js`);
|
||||
console.log(pm2Result);
|
||||
|
||||
console.log("Deployment completed successfully!");
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
const https = require('https');
|
||||
|
||||
const ROUTES = [
|
||||
'/',
|
||||
'/agents',
|
||||
'/apps',
|
||||
'/devices',
|
||||
'/dns',
|
||||
'/dpi-analytics',
|
||||
'/encryption-audit',
|
||||
'/events',
|
||||
'/flows',
|
||||
'/geography',
|
||||
'/intelligence',
|
||||
'/lookup',
|
||||
'/network-infrastructure',
|
||||
'/network-intelligence',
|
||||
'/network-topology',
|
||||
'/security-audit',
|
||||
'/threat-intelligence',
|
||||
'/threats',
|
||||
'/traffic-categories',
|
||||
'/help',
|
||||
'/login'
|
||||
];
|
||||
|
||||
function auditRoute(route) {
|
||||
return new Promise((resolve) => {
|
||||
https.get(`https://demoplace.my.id${route}`, (res) => {
|
||||
let data = '';
|
||||
res.on('data', c => data += c);
|
||||
res.on('end', () => {
|
||||
const title = (data.match(/<title>(.*?)<\/title>/i) || [])[1] || 'N/A';
|
||||
const desc = (data.match(/<meta name="description" content="(.*?)"/i) || [])[1] || 'N/A';
|
||||
const icons = [];
|
||||
const iconMatches = data.matchAll(/rel="icon" href="([^"]+)"/gi);
|
||||
for (const m of iconMatches) icons.push(m[1]);
|
||||
|
||||
const imgs = [];
|
||||
const imgMatches = data.matchAll(/src="([^"]*(?:logo|brand|icon|png|svg|jpg)[^"]*)"/gi);
|
||||
for (const m of imgMatches) {
|
||||
if (!imgs.includes(m[1])) imgs.push(m[1]);
|
||||
}
|
||||
|
||||
const headers = [];
|
||||
const hMatches = data.matchAll(/<h[123][^>]*>(.*?)<\/h[123]>/gi);
|
||||
for (const m of hMatches) {
|
||||
const clean = m[1].replace(/<[^>]+>/g, '').trim();
|
||||
if (clean && !headers.includes(clean)) headers.push(clean);
|
||||
}
|
||||
|
||||
resolve({
|
||||
route,
|
||||
status: res.statusCode,
|
||||
is404: data.includes('404: This page could not be found'),
|
||||
title,
|
||||
desc,
|
||||
icons,
|
||||
imgs,
|
||||
headers
|
||||
});
|
||||
});
|
||||
}).on('error', err => resolve({ route, error: err.message }));
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('=== DETAILED AUDIT OF DEMOPLACE.MY.ID ===\n');
|
||||
for (const r of ROUTES) {
|
||||
const res = await auditRoute(r);
|
||||
if (res.is404) {
|
||||
console.log(`❌ [404 NOT FOUND] ${res.route}`);
|
||||
} else {
|
||||
console.log(`✅ [200 OK] ${res.route}`);
|
||||
console.log(` Title : ${res.title}`);
|
||||
console.log(` Icons : ${res.icons.join(', ')}`);
|
||||
console.log(` Images/Logo: ${res.imgs.join(', ')}`);
|
||||
console.log(` Headers : ${res.headers.join(' | ')}`);
|
||||
}
|
||||
console.log('--------------------------------------------------');
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,18 @@
|
||||
const { Client } = require('ssh2');
|
||||
|
||||
const conn = new Client();
|
||||
conn.on('ready', () => {
|
||||
conn.exec(`ls -la /home/adminbackend/web/demoplace.my.id/public_html/.next/standalone/.next/server/app/\\(dashboard\\)/ 2>/dev/null || ls -la /home/adminbackend/web/demoplace.my.id/public_html/.next/server/app/`, (err, stream) => {
|
||||
let out = '';
|
||||
stream.on('data', d => out += d);
|
||||
stream.on('close', () => {
|
||||
console.log('=== REMOTE DASHBOARD APP ROUTES ===\n' + out);
|
||||
conn.end();
|
||||
});
|
||||
});
|
||||
}).connect({
|
||||
host: '103.185.47.52',
|
||||
port: 2222,
|
||||
username: 'adminbackend',
|
||||
password: 'htEo7x6LsBQiEHHH'
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
if (typeof globalThis.crypto === 'undefined') {
|
||||
globalThis.crypto = require('crypto');
|
||||
}
|
||||
const mongoose = require('mongoose');
|
||||
const path = require('path');
|
||||
require('dotenv').config({ path: path.join(__dirname, '..', '.env.production') });
|
||||
|
||||
const MONGODB_URI = process.env.MONGODB_URI;
|
||||
const { collectAllAgents } = require('../proxy/collector');
|
||||
|
||||
async function run() {
|
||||
console.log('[Trigger] Connecting to MongoDB...');
|
||||
await mongoose.connect(MONGODB_URI);
|
||||
console.log('[Trigger] Connected. Starting collection cycle...');
|
||||
try {
|
||||
const res = await collectAllAgents();
|
||||
console.log('[Trigger] Collection cycle finished successfully:', res);
|
||||
} catch (err) {
|
||||
console.error('[Trigger] Collection cycle failed:', err);
|
||||
} finally {
|
||||
await mongoose.connection.close();
|
||||
console.log('[Trigger] MongoDB connection closed.');
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
|
||||
Reference in new issue
Block a user