From a7d8654d3cb1fca12ddfc80783d81ec6a3af6580 Mon Sep 17 00:00:00 2001 From: MrUnknownDE Date: Fri, 2 Jan 2026 17:56:31 +0100 Subject: [PATCH] feat: Add initial frontend logic for network utilities (IP info, lookup, traceroute, port scan) and a backend route for MAC lookup. --- backend/package-lock.json | 19 +++++++++++++++++++ backend/package.json | 1 + backend/routes/macLookup.js | 33 +++++++++++++++++++-------------- frontend/app/script.js | 7 ++++--- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 407db19..8ee57c4 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -16,6 +16,7 @@ "express": "^4.21.2", "express-rate-limit": "^7.5.0", "macaddress": "^0.5.3", + "oui": "^13.1.1", "pino": "^9.6.0", "pino-pretty": "^13.0.0", "qs": "^6.14.1", @@ -1735,6 +1736,24 @@ "wrappy": "1" } }, + "node_modules/oui": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/oui/-/oui-13.1.1.tgz", + "integrity": "sha512-kv8YMm3UT8Rn5g2N7laIZfgcuWFhuLdyO3D9y3tTe1uBPNaNJMdLSkeb0l8C9jl7H4vgJ3GFfUv9gjVP9CQDmg==", + "license": "BSD-2-Clause", + "dependencies": { + "oui-data": "^1.1.428" + }, + "bin": { + "oui": "dist/index.js" + } + }, + "node_modules/oui-data": { + "version": "1.1.476", + "resolved": "https://registry.npmjs.org/oui-data/-/oui-data-1.1.476.tgz", + "integrity": "sha512-TTcraRcKV4TTLex4261J2w0AMjq8X5Mj0u4FfIBqLXPSCz+sh37Zdk5g383i7fidoMW+SSfQ1POunNrYenYzKQ==", + "license": "BSD-2-Clause" + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", diff --git a/backend/package.json b/backend/package.json index 09cc24e..e0ed97f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -17,6 +17,7 @@ "express": "^4.21.2", "express-rate-limit": "^7.5.0", "macaddress": "^0.5.3", + "oui": "^13.1.1", "pino": "^9.6.0", "pino-pretty": "^13.0.0", "qs": "^6.14.1", diff --git a/backend/routes/macLookup.js b/backend/routes/macLookup.js index 1761fb3..3d19281 100644 --- a/backend/routes/macLookup.js +++ b/backend/routes/macLookup.js @@ -1,6 +1,6 @@ const express = require('express'); const Sentry = require("@sentry/node"); -const macaddress = require('macaddress'); +const oui = require('oui'); const pino = require('pino'); const { isValidMacAddress } = require('../utils'); @@ -19,16 +19,17 @@ router.get('/', async (req, res) => { return res.status(400).json({ success: false, error: 'Invalid MAC address format provided.' }); } + // Use 'oui' library to find vendor try { - // Wrap the callback-based function in a Promise to use it with async/await - const vendor = await new Promise((resolve, reject) => { - macaddress.lookup(mac, (err, vendorString) => { - if (err) { - return reject(err); - } - resolve(vendorString); - }); - }); + const ouiData = oui(mac); + // oui returns a string (Vendor Name) or null if not found + // Sometimes it returns an object? The documentation says it returns the organization name string. + // Let's handle both just in case, but usually it's a string or null. + + let vendor = null; + if (ouiData) { + vendor = typeof ouiData === 'string' ? ouiData : ouiData.split('\n')[0]; + } if (vendor) { logger.info({ requestIp, mac, vendor }, 'MAC lookup successful'); @@ -37,11 +38,15 @@ router.get('/', async (req, res) => { logger.info({ requestIp, mac }, 'MAC address not found in OUI database'); res.status(404).json({ success: false, error: 'Vendor not found for this MAC address.' }); } - } catch (error) { - logger.error({ requestIp, mac, error: error.message }, 'MAC lookup failed'); - Sentry.captureException(error, { extra: { requestIp, mac } }); - res.status(500).json({ success: false, error: 'An unexpected error occurred during the MAC lookup.' }); + } catch (err) { + // oui might throw on invalid input, though we validated it. + throw err; } +} catch (error) { + logger.error({ requestIp, mac, error: error.message }, 'MAC lookup failed'); + Sentry.captureException(error, { extra: { requestIp, mac } }); + res.status(500).json({ success: false, error: 'An unexpected error occurred during the MAC lookup.' }); +} }); module.exports = router; \ No newline at end of file diff --git a/frontend/app/script.js b/frontend/app/script.js index 058daaa..b2202f4 100644 --- a/frontend/app/script.js +++ b/frontend/app/script.js @@ -215,9 +215,10 @@ document.addEventListener('DOMContentLoaded', () => { } else { try { mapInstance = L.map(mapId).setView([lat, lon], 13); - L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - maxZoom: 19, - attribution: '© OpenStreetMap contributors' + L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { + attribution: '© OpenStreetMap contributors © CARTO', + subdomains: 'abcd', + maxZoom: 19 }).addTo(mapInstance); L.marker([lat, lon]).addTo(mapInstance).bindPopup(`Approximate Location`).openPopup(); window[mapId + '_instance'] = mapInstance; // Store instance