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