mirror of
https://github.com/Lissy93/web-check.git
synced 2025-02-16 18:30:48 +01:00
Writes lambdas for DNSSEC, site features, carbon footprint and more
This commit is contained in:
parent
b8705ee48e
commit
7d33c38897
15
netlify.toml
15
netlify.toml
@ -81,6 +81,21 @@
|
||||
to = "/.netlify/functions/trace-route"
|
||||
status = 301
|
||||
force = true
|
||||
[[redirects]]
|
||||
from = "/get-carbon"
|
||||
to = "/.netlify/functions/get-carbon"
|
||||
status = 301
|
||||
force = true
|
||||
[[redirects]]
|
||||
from = "/site-features"
|
||||
to = "/.netlify/functions/site-features"
|
||||
status = 301
|
||||
force = true
|
||||
[[redirects]]
|
||||
from = "/dns-sec"
|
||||
to = "/.netlify/functions/dns-sec"
|
||||
status = 301
|
||||
force = true
|
||||
|
||||
# For router history mode, ensure pages land on index
|
||||
[[redirects]]
|
||||
|
@ -1,7 +1,12 @@
|
||||
const net = require('net');
|
||||
|
||||
// A list of commonly used ports.
|
||||
const PORTS = [21, 22, 25, 80, 110, 143, 443, 587, 993, 995, 3306, 3389, 5900, 8080];
|
||||
const PORTS = [
|
||||
20, 21, 22, 23, 25, 53, 80, 67, 68, 69,
|
||||
110, 119, 123, 143, 156, 161, 162, 179, 194,
|
||||
389, 443, 587, 993, 995,
|
||||
3000, 3306, 3389, 5060, 5900, 8000, 8080, 8888
|
||||
];
|
||||
|
||||
async function checkPort(port, domain) {
|
||||
return new Promise(resolve => {
|
||||
|
69
server/lambda/dns-sec.js
Normal file
69
server/lambda/dns-sec.js
Normal file
@ -0,0 +1,69 @@
|
||||
const https = require('https');
|
||||
const urlModule = require('url');
|
||||
|
||||
exports.handler = async function(event, context) {
|
||||
let { url } = event.queryStringParameters;
|
||||
|
||||
if (!url) {
|
||||
return {
|
||||
statusCode: 400,
|
||||
body: JSON.stringify({ error: 'url query parameter is required' }),
|
||||
};
|
||||
}
|
||||
|
||||
// Extract hostname from URL
|
||||
const parsedUrl = new URL(url);
|
||||
const domain = parsedUrl.hostname;
|
||||
|
||||
const dnsTypes = ['DNSKEY', 'DS', 'RRSIG'];
|
||||
const records = {};
|
||||
|
||||
for (const type of dnsTypes) {
|
||||
const options = {
|
||||
hostname: 'dns.google',
|
||||
path: `/resolve?name=${encodeURIComponent(domain)}&type=${type}`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/dns-json'
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const dnsResponse = await new Promise((resolve, reject) => {
|
||||
const req = https.request(options, res => {
|
||||
let data = '';
|
||||
|
||||
res.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
resolve(JSON.parse(data));
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', error => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
req.end();
|
||||
});
|
||||
|
||||
if (dnsResponse.Answer) {
|
||||
records[type] = { isFound: true, answer: dnsResponse.Answer, response: dnsResponse.Answer };
|
||||
} else {
|
||||
records[type] = { isFound: false, answer: null, response: dnsResponse};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({ error: `Error fetching ${type} record: ${error.message}` }),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify(records),
|
||||
};
|
||||
};
|
55
server/lambda/get-carbon.js
Normal file
55
server/lambda/get-carbon.js
Normal file
@ -0,0 +1,55 @@
|
||||
const https = require('https');
|
||||
|
||||
exports.handler = async (event, context) => {
|
||||
const { url } = event.queryStringParameters;
|
||||
|
||||
if (!url) {
|
||||
return {
|
||||
statusCode: 400,
|
||||
body: JSON.stringify({ message: 'url query parameter is required' }),
|
||||
};
|
||||
}
|
||||
|
||||
// First, get the size of the website's HTML
|
||||
const getHtmlSize = (url) => new Promise((resolve, reject) => {
|
||||
https.get(url, res => {
|
||||
let data = '';
|
||||
res.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
const sizeInBytes = Buffer.byteLength(data, 'utf8');
|
||||
resolve(sizeInBytes);
|
||||
});
|
||||
}).on('error', reject);
|
||||
});
|
||||
|
||||
try {
|
||||
const sizeInBytes = await getHtmlSize(url);
|
||||
const apiUrl = `https://api.websitecarbon.com/data?bytes=${sizeInBytes}&green=0`;
|
||||
|
||||
// Then use that size to get the carbon data
|
||||
const carbonData = await new Promise((resolve, reject) => {
|
||||
https.get(apiUrl, res => {
|
||||
let data = '';
|
||||
res.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
resolve(JSON.parse(data));
|
||||
});
|
||||
}).on('error', reject);
|
||||
});
|
||||
|
||||
carbonData.scanUrl = url;
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify(carbonData),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({ message: `Error: ${error.message}` }),
|
||||
};
|
||||
}
|
||||
};
|
44
server/lambda/site-features.js
Normal file
44
server/lambda/site-features.js
Normal file
@ -0,0 +1,44 @@
|
||||
const https = require('https');
|
||||
|
||||
exports.handler = async function (event, context) {
|
||||
const { url } = event.queryStringParameters;
|
||||
const apiKey = process.env.BUILT_WITH_API_KEY;
|
||||
|
||||
const errorResponse = (message, statusCode = 444) => {
|
||||
return {
|
||||
statusCode: statusCode,
|
||||
body: JSON.stringify({ error: message }),
|
||||
};
|
||||
};
|
||||
|
||||
if (!url) {
|
||||
return errorResponse('url query parameter is required', 400);
|
||||
}
|
||||
|
||||
const apiUrl = `https://api.builtwith.com/free1/api.json?KEY=${apiKey}&LOOKUP=${encodeURIComponent(url)}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get(apiUrl, (res) => {
|
||||
let data = '';
|
||||
|
||||
// A chunk of data has been received.
|
||||
res.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
// The whole response has been received.
|
||||
res.on('end', () => {
|
||||
if(res.statusCode !== 200){
|
||||
resolve(errorResponse(`Request failed with status code: ${res.statusCode}`));
|
||||
} else {
|
||||
resolve({
|
||||
statusCode: 200,
|
||||
body: data,
|
||||
});
|
||||
}
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
resolve(errorResponse(`Error making request: ${err.message}`, 500));
|
||||
});
|
||||
});
|
||||
};
|
@ -1,28 +1,45 @@
|
||||
const https = require('https');
|
||||
const { stringify } = require('flatted');
|
||||
|
||||
exports.handler = async function (event, context) {
|
||||
const { url } = event.queryStringParameters;
|
||||
|
||||
const errorResponse = (message, statusCode = 444) => {
|
||||
return {
|
||||
statusCode: statusCode,
|
||||
body: JSON.stringify({ error: message }),
|
||||
};
|
||||
};
|
||||
|
||||
if (!url) {
|
||||
return {
|
||||
statusCode: 400,
|
||||
body: 'url query parameter is required',
|
||||
body: errorResponse('url query parameter is required'),
|
||||
};
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.request(url, res => {
|
||||
resolve({
|
||||
statusCode: 200,
|
||||
body: JSON.stringify(res.socket.getPeerCertificate()),
|
||||
});
|
||||
|
||||
// Check if the SSL handshake was authorized
|
||||
if (!res.socket.authorized) {
|
||||
resolve(errorResponse(`SSL handshake not authorized. Reason: ${res.socket.authorizationError}`));
|
||||
} else {
|
||||
const cert = res.socket.getPeerCertificate(true);
|
||||
if (!cert || Object.keys(cert).length === 0) {
|
||||
resolve(errorResponse("No certificate presented by the server."));
|
||||
} else {
|
||||
resolve({
|
||||
statusCode: 200,
|
||||
body: stringify(cert),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
req.on('error', (error) => {
|
||||
resolve({
|
||||
statusCode: 500,
|
||||
body: `Error fetching site certificate: ${error.message}`,
|
||||
});
|
||||
resolve(
|
||||
errorResponse(`Error fetching site certificate: ${error.message}`, 500));
|
||||
});
|
||||
|
||||
req.end();
|
||||
|
Loading…
Reference in New Issue
Block a user