mirror of
https://github.com/MrUnknownDE/utools.git
synced 2026-04-09 18:03:52 +02:00
feat: Add initial frontend logic for network utilities (IP info, lookup, traceroute, port scan) and a backend route for MAC lookup.
This commit is contained in:
19
backend/package-lock.json
generated
19
backend/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
@@ -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: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
subdomains: 'abcd',
|
||||
maxZoom: 19
|
||||
}).addTo(mapInstance);
|
||||
L.marker([lat, lon]).addTo(mapInstance).bindPopup(`Approximate Location`).openPopup();
|
||||
window[mapId + '_instance'] = mapInstance; // Store instance
|
||||
|
||||
Reference in New Issue
Block a user