Files
utools/backend/routes/whoisLookup.js

91 lines
4.6 KiB
JavaScript

// backend/routes/whoisLookup.js
const express = require('express');
const Sentry = require("@sentry/node");
const whois = require('whois-json');
const pino = require('pino');
// Import utilities
const { isValidIp, isValidDomain, isPrivateIp } = require('../utils');
// Logger for this module
const logger = pino({ level: process.env.LOG_LEVEL || 'info' });
const router = express.Router();
// Route handler for / (relative to /api/whois-lookup)
router.get('/', async (req, res, next) => {
const queryRaw = req.query.query;
const query = typeof queryRaw === 'string' ? queryRaw.trim() : queryRaw;
const requestIp = req.ip || req.socket.remoteAddress;
logger.info({ requestIp, query }, 'WHOIS lookup request received');
// Validate if the query is either a valid IP or a valid domain
if (!isValidIp(query) && !isValidDomain(query)) {
logger.warn({ requestIp, query }, 'Invalid query for WHOIS lookup');
return res.status(400).json({ success: false, error: 'Invalid domain name or IP address provided for WHOIS lookup.' });
}
if (isValidIp(query) && isPrivateIp(query)) {
logger.warn({ requestIp, query }, 'Attempt to WHOIS lookup private IP blocked');
return res.status(403).json({ success: false, error: 'WHOIS lookup for private or local IP addresses is not supported.' });
}
// Note: No isPrivateIp check here, as WHOIS for IPs might be desired regardless of range,
// and domain lookups don't involve IP ranges.
try {
// Execute WHOIS lookup with a timeout
const result = await whois(query, {
timeout: parseInt(process.env.WHOIS_TIMEOUT || '10000', 10), // Configurable timeout (default 10s), ensure integer
// follow: 3, // Optional: limit number of redirects followed
// verbose: true // Optional: get raw text output as well
});
// Check if the result indicates an error (some servers return structured errors)
// This check might need adjustment based on the 'whois-json' library's output for errors.
if (result && (result.error || result.Error)) {
logger.warn({ requestIp, query, whoisResult: result }, 'WHOIS lookup returned an error structure');
return res.status(404).json({ success: false, error: `WHOIS lookup failed: ${result.error || result.Error}`, result });
}
// Basic check if the result is empty or just contains the query itself (might indicate no data)
if (!result || Object.keys(result).length === 0 || (Object.keys(result).length === 1 && (result.domainName === query || result.query === query))) {
logger.info({ requestIp, query }, 'WHOIS lookup returned no detailed data.');
// Consider 404 Not Found if no data is available
return res.status(404).json({ success: false, error: 'No detailed WHOIS information found for the query.', query });
}
logger.info({ requestIp, query }, 'WHOIS lookup successful');
res.json({ success: true, query, result });
} catch (error) {
logger.error({ requestIp, query, error: error.message }, 'WHOIS lookup failed');
Sentry.captureException(error, { extra: { requestIp, query } });
// Provide more user-friendly error messages based on common errors
let errorMessage = error.message;
let statusCode = 500; // Default to Internal Server Error
if (error.message.includes('ETIMEDOUT') || error.message.includes('ESOCKETTIMEDOUT')) {
errorMessage = 'WHOIS server timed out.';
statusCode = 504; // Gateway Timeout
} else if (error.message.includes('ENOTFOUND')) {
// This might indicate the domain doesn't exist or the WHOIS server for the TLD couldn't be found
errorMessage = 'Domain or IP not found, or the corresponding WHOIS server is unavailable.';
statusCode = 404; // Not Found
} else if (error.message.includes('ECONNREFUSED')) {
errorMessage = 'Connection to WHOIS server refused.';
statusCode = 503; // Service Unavailable
} else if (error.message.includes('No WHOIS server found for')) {
errorMessage = 'Could not find a WHOIS server for the requested domain/TLD.';
statusCode = 404; // Not Found (as the server for it isn't known)
}
// Add more specific error handling if needed based on observed errors
res.status(statusCode).json({ success: false, error: `WHOIS lookup failed: ${errorMessage}` });
// next(error); // Optional: Pass to Sentry error handler
}
});
module.exports = router;