diff --git a/scripts/audit-all-pages-content.js b/scripts/audit-all-pages-content.js new file mode 100644 index 0000000..b40c055 --- /dev/null +++ b/scripts/audit-all-pages-content.js @@ -0,0 +1,66 @@ +const { Client } = require('ssh2'); + +const remoteScript = ` +const fs = require('fs'); +const path = require('path'); + +const root = '/home/adminbackend/web/demoplace.my.id/public_html/.next/standalone/.next/server/app/(dashboard)'; + +function scanDir(dir) { + const results = []; + if (!fs.existsSync(dir)) return results; + const items = fs.readdirSync(dir, { withFileTypes: true }); + for (const item of items) { + const fullPath = path.join(dir, item.name); + if (item.isDirectory()) { + results.push(...scanDir(fullPath)); + } else if (item.name.endsWith('.html') || item.name.endsWith('.js')) { + results.push(fullPath); + } + } + return results; +} + +console.log('=== AUDITING ALL PAGE HEADERS AND TITLES ON DEMOPLACE.MY.ID ===\\n'); + +const files = scanDir(root); +files.forEach(file => { + const content = fs.readFileSync(file, 'utf8'); + const rel = path.relative(root, file); + + // Extract

or

or header titles + const h2s = []; + const h2Match = content.matchAll(/]*>(.*?)<\/h2>/gi); + for (const m of h2Match) { + const clean = m[1].replace(/<[^>]+>/g, '').trim(); + if (clean && !h2s.includes(clean)) h2s.push(clean); + } + + // Extract Learn This Page triggers + const hasHelpTrigger = content.includes('Learn This Page'); + + if (h2s.length > 0 || hasHelpTrigger) { + console.log('Page Route File:', rel); + if (h2s.length > 0) console.log(' Headers (H2):', h2s.join(' | ')); + console.log(' Has Learn This Page Button:', hasHelpTrigger); + console.log('---'); + } +}); +`; + +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' +}); diff --git a/scripts/extract-all-client-titles.js b/scripts/extract-all-client-titles.js new file mode 100644 index 0000000..427bc98 --- /dev/null +++ b/scripts/extract-all-client-titles.js @@ -0,0 +1,62 @@ +const SftpClient = require('ssh2-sftp-client'); +const { Client } = require('ssh2'); + +const remoteExtractScript = ` +const fs = require('fs'); +const path = require('path'); + +const root = '/home/adminbackend/web/demoplace.my.id/public_html/.next/standalone/.next/server/chunks'; + +console.log('=== EXTRACTING ALL PAGE HEADERS FROM CHUNKS ===\\n'); + +const files = fs.readdirSync(root); +files.forEach(f => { + if (!f.endsWith('.js')) return; + const content = fs.readFileSync(path.join(root, f), 'utf8'); + + // Match header titles in React JSX: e.g. text-3xl font-bold ... >TitleText< + const titleMatches = content.matchAll(/text-3xl[^>]*>([^<]{3,40})]*>([^<]{3,30}) { + conn.exec(`node ${remoteScriptPath}`, (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' + }); +} + +main(); diff --git a/scripts/extract-standalone-headers.js b/scripts/extract-standalone-headers.js new file mode 100644 index 0000000..ef962df --- /dev/null +++ b/scripts/extract-standalone-headers.js @@ -0,0 +1,69 @@ +const SftpClient = require('ssh2-sftp-client'); +const { Client } = require('ssh2'); + +const remoteExtractScript = ` +const fs = require('fs'); +const path = require('path'); + +const root = '/home/adminbackend/web/demoplace.my.id/public_html/.next/standalone/.next/server'; + +console.log('=== EXTRACTING ALL PAGE HEADERS FROM STANDALONE BUILD ===\\n'); + +function scan(dir) { + if (!fs.existsSync(dir)) return; + const items = fs.readdirSync(dir, { withFileTypes: true }); + for (const item of items) { + const full = path.join(dir, item.name); + if (item.isDirectory()) { + scan(full); + } else if (item.name.endsWith('.js') || item.name.endsWith('.html')) { + const content = fs.readFileSync(full, 'utf8'); + + // Look for H2/H1 page header titles or page metadata + const matches = content.matchAll(/]*>([\\s\\S]*?)<\\/h[12]>/gi); + for (const m of matches) { + const clean = m[1].replace(/<[^>]+>/g, '').trim(); + if (clean && clean.length > 2 && clean.length < 60 && !clean.includes('{') && !clean.includes('function')) { + console.log(\`File: \${path.relative(root, full)}\`); + console.log(\` Header: "\${clean}"\`); + } + } + } + } +} + +scan(path.join(root, 'app/(dashboard)')); +`; + +async function main() { + const sftp = new SftpClient(); + await sftp.connect({ + host: '103.185.47.52', + port: 2222, + username: 'adminbackend', + password: 'htEo7x6LsBQiEHHH' + }); + + const remoteScriptPath = '/home/adminbackend/extract_standalone.js'; + await sftp.put(Buffer.from(remoteExtractScript), remoteScriptPath); + await sftp.end(); + + const conn = new Client(); + conn.on('ready', () => { + conn.exec(`node ${remoteScriptPath}`, (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' + }); +} + +main(); diff --git a/scripts/remote-audit-runner.js b/scripts/remote-audit-runner.js new file mode 100644 index 0000000..97791c4 --- /dev/null +++ b/scripts/remote-audit-runner.js @@ -0,0 +1,44 @@ +const { Client } = require('ssh2'); + +const conn = new Client(); +conn.on('ready', () => { + // Execute a shell script on remote server + conn.exec(`python3 -c " +import os, re + +root = '/home/adminbackend/web/demoplace.my.id/public_html/.next/standalone/.next/server/app/(dashboard)' + +for dirpath, dirnames, filenames in os.walk(root): + for f in filenames: + if f.endswith('.html') or f.endswith('.js'): + full = os.path.join(dirpath, f) + rel = os.path.relpath(full, root) + try: + content = open(full, 'r', encoding='utf-8', errors='ignore').read() + + h2s = re.findall(r']*>(.*?)', content) + clean_h2s = [re.sub(r'<[^>]+>', '', h).strip() for h in h2s if h.strip()] + + has_learn = 'Learn This Page' in content + + if clean_h2s or has_learn: + print(f'Route File: {rel}') + print(f' Headers: {\" | \".join(clean_h2s)}') + print(f' Learn This Page Button: {has_learn}') + print('-' * 40) + except Exception as e: + pass +"`, (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' +}); diff --git a/scripts/scan-all-string-literals.js b/scripts/scan-all-string-literals.js new file mode 100644 index 0000000..5b367a6 --- /dev/null +++ b/scripts/scan-all-string-literals.js @@ -0,0 +1,80 @@ +const SftpClient = require('ssh2-sftp-client'); +const { Client } = require('ssh2'); + +const remoteScanScript = ` +const fs = require('fs'); +const path = require('path'); + +const root = '/home/adminbackend/web/demoplace.my.id/public_html/.next'; + +const targetTitles = [ + 'Overview Dashboard', + 'Summary Overview', + 'DPI MetaData', + 'BackOne Metadata', + 'Network Topology', + 'Network Infrastructure', + 'Traffic Categories', + 'Threat Intelligence', + 'Detected Threats', + 'App Lookup', + 'Application Database', + 'Encryption Audit', + 'Security & Encryption Audit' +]; + +console.log('=== MATCHING TARGET TITLES IN REMOTE NEXT BUILD ===\\n'); + +function scan(dir) { + if (!fs.existsSync(dir)) return; + const items = fs.readdirSync(dir, { withFileTypes: true }); + for (const item of items) { + const full = path.join(dir, item.name); + if (item.isDirectory()) { + scan(full); + } else if (item.name.endsWith('.js') || item.name.endsWith('.html')) { + const content = fs.readFileSync(full, 'utf8'); + targetTitles.forEach(t => { + if (content.includes(t)) { + console.log(\`Found "\${t}" in file: \${path.relative(root, full)}\`); + } + }); + } + } +} + +scan(root); +`; + +async function main() { + const sftp = new SftpClient(); + await sftp.connect({ + host: '103.185.47.52', + port: 2222, + username: 'adminbackend', + password: 'htEo7x6LsBQiEHHH' + }); + + const remoteScriptPath = '/home/adminbackend/scan_strings.js'; + await sftp.put(Buffer.from(remoteScanScript), remoteScriptPath); + await sftp.end(); + + const conn = new Client(); + conn.on('ready', () => { + conn.exec(`node ${remoteScriptPath}`, (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' + }); +} + +main(); diff --git a/scripts/upload-and-run-audit.js b/scripts/upload-and-run-audit.js new file mode 100644 index 0000000..c8970b7 --- /dev/null +++ b/scripts/upload-and-run-audit.js @@ -0,0 +1,94 @@ +const SftpClient = require('ssh2-sftp-client'); +const { Client } = require('ssh2'); + +const remoteAuditScript = ` +const fs = require('fs'); +const path = require('path'); + +const root = '/home/adminbackend/web/demoplace.my.id/public_html'; + +console.log('===================================================='); +console.log(' FULL COMPONENT & PAGE AUDIT OF DEMOPLACE.MY.ID '); +console.log('===================================================='); + +// 1. Audit Client/Server Chunks for Page Headers & HelpTriggers +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'); + + // Look for page headers or title definitions + const headerMatch = content.match(/["']([A-Z][A-Za-z0-9\\s]{3,35})["'],\\s*description:/); + if (headerMatch) { + console.log(\`[Chunk \${f}] Found Header Definition: "\${headerMatch[1]}"\`); + } + + if (content.includes('Learn This Page')) { + console.log(\`[Chunk \${f}] Contains "Learn This Page" button\`); + } + }); +} + +// 2. Audit Page Source files in src/app/(dashboard) +const appSrcDir = path.join(root, 'src/app/(dashboard)'); +if (fs.existsSync(appSrcDir)) { + function scan(dir) { + const items = fs.readdirSync(dir, { withFileTypes: true }); + for (const item of items) { + const full = path.join(dir, item.name); + if (item.isDirectory()) { + scan(full); + } else if (item.name === 'page.tsx' || item.name.endsWith('.tsx')) { + const content = fs.readFileSync(full, 'utf8'); + const rel = path.relative(appSrcDir, full); + + // Find H2 or H1 + const h2 = content.match(/]*>([\\s\\S]*?)<\\/h[12]>/i); + const titleText = h2 ? h2[1].replace(/<[^>]+>/g, '').trim().split('\\n')[0] : 'None'; + const hasHelp = content.includes('HelpTrigger') || content.includes('Learn This Page'); + + console.log(\`Page File: \${rel}\`); + console.log(\` Header Title : \${titleText}\`); + console.log(\` Has HelpButton: \${hasHelp}\`); + console.log('----------------------------------------------------'); + } + } + } + scan(appSrcDir); +} +`; + +async function main() { + const sftp = new SftpClient(); + await sftp.connect({ + host: '103.185.47.52', + port: 2222, + username: 'adminbackend', + password: 'htEo7x6LsBQiEHHH' + }); + + const remoteScriptPath = '/home/adminbackend/audit_remote.js'; + await sftp.put(Buffer.from(remoteAuditScript), remoteScriptPath); + await sftp.end(); + + const conn = new Client(); + conn.on('ready', () => { + conn.exec(`node ${remoteScriptPath}`, (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' + }); +} + +main(); diff --git a/src/app/(dashboard)/agents/page.tsx b/src/app/(dashboard)/agents/page.tsx index 32255cc..64d0df1 100644 --- a/src/app/(dashboard)/agents/page.tsx +++ b/src/app/(dashboard)/agents/page.tsx @@ -14,6 +14,7 @@ import { usePollingKey } from "@/lib/usePolling"; import { AgentModals } from "@/components/admin/AgentModals"; import ExternalAccountModal from "@/components/admin/ExternalAccountModal"; import { getAgentColumns, getExternalAccountColumns } from "./columns"; +import { HelpTrigger } from "@/components/help/HelpTrigger"; export default function AgentsPage() { const router = useRouter(); @@ -175,20 +176,25 @@ export default function AgentsPage() { return (
-

- - Agents Inventory - {isLoading && } -

- {(role === 'SUPER_ADMIN' || role === 'TENANT_ADMIN') && ( - - )} +
+

+ Agents Inventory + {isLoading && } +

+

Managed DPI probes, remote collectors, and probe infrastructure.

+
+
+ {(role === 'SUPER_ADMIN' || role === 'TENANT_ADMIN') && ( + + )} + +
{error && ( diff --git a/src/app/(dashboard)/apps/page.tsx b/src/app/(dashboard)/apps/page.tsx index 5ae35d3..96bd4b0 100644 --- a/src/app/(dashboard)/apps/page.tsx +++ b/src/app/(dashboard)/apps/page.tsx @@ -11,6 +11,7 @@ import { Loader2, ChevronRight, Globe } from "lucide-react"; import { UniversalFilters, useUniversalFilterState, FilterConfig } from "@/components/ui/UniversalFilters"; import { fmtBytes, getAppFavicon, formatAppLabel } from "@/lib/utils"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, ResponsiveContainer } from "recharts"; +import { HelpTrigger } from "@/components/help/HelpTrigger"; export default function AppsPage() { const [mounted, setMounted] = useState(false); @@ -130,7 +131,7 @@ export default function AppsPage() {
-

+

Applications {isLoading && }

@@ -138,6 +139,7 @@ export default function AppsPage() { Click any application to see which agents and devices are using it.

+
Click an IP to see app usage & flows.

+
-
-

- DNS Intelligence - {isLoading && } -

+
+
+

+ DNS Intelligence + {isLoading && } +

+

Domain Name System resolution analytics and query logs.

+
+
-
-

BackOne Metadata

-

- Deep Packet Inspection metadata and fingerprinting.{" "} - Click any row to view device-level detail. -

+
+
+

DPI MetaData

+

+ Deep Packet Inspection metadata and fingerprinting.{" "} + Click any row to view device-level detail. +

+
+
diff --git a/src/app/(dashboard)/events/page.tsx b/src/app/(dashboard)/events/page.tsx index 0507755..724b046 100644 --- a/src/app/(dashboard)/events/page.tsx +++ b/src/app/(dashboard)/events/page.tsx @@ -11,6 +11,7 @@ import { UniversalFilters, useUniversalFilterState, FilterConfig } from "@/compo import { useSearchParams } from "next/navigation"; import { Suspense } from "react"; +import { HelpTrigger } from "@/components/help/HelpTrigger"; @@ -158,10 +159,14 @@ function EventsContent() { return (
-

- Network Events - {isLoading && } -

+
+

+ Network Events + {isLoading && } +

+

Real-time system, security, and interface network log events.

+
+
-

- Active Flows - {isLoading && } -

+
+

+ Active Flows + {isLoading && } +

+

Real-time IP connection flows and protocol analysis.

+
+
-
+

- Geographic Traffic + Geo Traffic {isLoading && }

-

Visualize data flow and activity across the globe.

+

Geographic distribution of inbound and outbound traffic by country.

+
-
-

- Threat Intelligence Feeds +
+
+

+ Threat Intelligence {loadingStats && }

+

Deep threat intelligence feeds and security detections.

+
+
diff --git a/src/app/(dashboard)/lookup/page.tsx b/src/app/(dashboard)/lookup/page.tsx index 4ad2d8b..6a52763 100644 --- a/src/app/(dashboard)/lookup/page.tsx +++ b/src/app/(dashboard)/lookup/page.tsx @@ -6,6 +6,8 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card"; import { DropdownFilterSelect } from "@/components/ui/DropdownFilterSelect"; import { Loader2, Search, AppWindow, HelpCircle, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, X, Info, Tag, Box, Shield, Server } from "lucide-react"; +import { HelpTrigger } from "@/components/help/HelpTrigger"; + export default function LookupPage() { const [mounted, setMounted] = useState(false); const [searchQuery, setSearchQuery] = useState(""); @@ -54,14 +56,17 @@ export default function LookupPage() { return (
-
-

- Application Database - {isLoading && } -

-

- Search BackOne's extensive classification database of over 2,500+ apps, protocols, and services. -

+
+
+

+ App Lookup + {isLoading && } +

+

+ Search BackOne's extensive classification database of over 2,500+ apps, protocols, and services. +

+
+
{/* Search & Filter Bar */} diff --git a/src/app/(dashboard)/network-infrastructure/page.tsx b/src/app/(dashboard)/network-infrastructure/page.tsx index b2cabf9..9dfdf0b 100644 --- a/src/app/(dashboard)/network-infrastructure/page.tsx +++ b/src/app/(dashboard)/network-infrastructure/page.tsx @@ -12,6 +12,8 @@ import { import { IpDetails } from "@/components/ui/IpDetails"; import { RemoteIpDetailModal } from "@/components/ui/RemoteIpDetailModal"; +import { HelpTrigger } from "@/components/help/HelpTrigger"; + export default function NetworkInfrastructurePage() { const [selectedRemoteIp, setSelectedRemoteIp] = useState(null); @@ -42,9 +44,12 @@ export default function NetworkInfrastructurePage() { return (
-
-

Network Infrastructure

-

Physical, logical, and geographic network topologies.

+
+
+

Network Topology

+

Physical, logical, and geographic network topologies.

+
+
diff --git a/src/app/(dashboard)/network-intelligence/page.tsx b/src/app/(dashboard)/network-intelligence/page.tsx index 9cba53b..437996d 100644 --- a/src/app/(dashboard)/network-intelligence/page.tsx +++ b/src/app/(dashboard)/network-intelligence/page.tsx @@ -13,6 +13,7 @@ import { useAppCategories, useContinents } from "@/lib/api-with-context"; import { fmtBytes } from "@/lib/utils"; import { UniversalFilters, useUniversalFilterState, FilterConfig } from "@/components/ui/UniversalFilters"; import { CategoryDetailPanel } from "@/components/network/CategoryDetailPanel"; +import { HelpTrigger } from "@/components/help/HelpTrigger"; const COLORS = ['#58a6ff', '#3fb950', '#f0883e', '#bc8cff', '#f85149']; @@ -90,6 +91,7 @@ export default function NetworkIntelligencePage() {

Deep packet inspection analytics and geography.

+
-
-

Security & Encryption Audit

-

- Monitor TLS versions distribution, cipher suites, active certificate properties, and device risk profiles. -

+
+
+

Encryption Audit

+

+ Monitor TLS versions distribution, cipher suites, active certificate properties, and device risk profiles. +

+
+

- Threat Intelligence + Detected Threats {threats.isLoading && }

Monitor and respond to network security threats.

-
- - Active Monitoring +
+
+ + Active Monitoring +
+