diff --git a/api/carbon.js b/api/carbon.js
index a08d530..97531c4 100644
--- a/api/carbon.js
+++ b/api/carbon.js
@@ -7,25 +7,23 @@ const log = createLogger('carbon');
const TIMEOUT = 8000;
const MAX_BYTES = 10 * 1024 * 1024;
-// Sustainable Web Design model v3 constants, matches websitecarbon.com formula
-const KWH_PER_GB = 0.81;
+// Sustainable Web Design model v4 constants, matches websitecarbon.com formula
+const KWH_PER_GB = 0.3;
const FIRST_VISIT = 0.25;
const RETURN_VISIT = 0.75;
const RETURN_DATA_PCT = 0.02;
-const GRID_INTENSITY = 442;
+const GRID_INTENSITY = 494;
const RENEWABLE_INTENSITY = 50;
const LITRES_PER_GRAM = 0.5562;
-// Reference median grams CO2 per visit, drawn from websitecarbon's published average.
-// Used to estimate a percentile rank since we lack their measured-sites dataset
-const REFERENCE_MEDIAN_GRAMS = 0.8;
+// Median CO2 for an HTML-only fetch at HTTP Archive's ~30 KB median
+const REFERENCE_MEDIAN_GRAMS = 0.001;
-// Approximate percentile via log2 distance from the reference median.
-// 1 doubling above median drops 25 points; clamp to [1, 99]
+// Percentile rank via log2 distance from the median, clamped to [1, 95]
const estimateCleanerThan = (grams) => {
if (!grams || grams <= 0) return 0;
- const pct = 50 - 25 * Math.log2(grams / REFERENCE_MEDIAN_GRAMS);
- return Math.max(1, Math.min(99, Math.round(pct)));
+ const pct = 50 - 15 * Math.log2(grams / REFERENCE_MEDIAN_GRAMS);
+ return Math.max(1, Math.min(95, Math.round(pct)));
};
// Stream the response, cap at MAX_BYTES so huge pages can't blow memory or time
diff --git a/api/rank.js b/api/rank.js
index b44c874..3625fa5 100644
--- a/api/rank.js
+++ b/api/rank.js
@@ -4,19 +4,24 @@ import { parseTarget } from './_common/parse-target.js';
import { upstreamError } from './_common/upstream.js';
const rankHandler = async (url) => {
- const { hostname: domain } = parseTarget(url);
+ const { hostname } = parseTarget(url);
const { TRANCO_USERNAME, TRANCO_API_KEY } = process.env;
const auth = TRANCO_API_KEY
? { auth: { username: TRANCO_USERNAME, password: TRANCO_API_KEY } }
: {};
+ const fallback = hostname.startsWith('www.') ? hostname.slice(4) : `www.${hostname}`;
+ // Tranco indexes only one variant per site, so try as-is, then toggle www
+ const lookup = (domain) => httpGet(`https://tranco-list.eu/api/ranks/domain/${domain}`, auth);
try {
- const response = await httpGet(`https://tranco-list.eu/api/ranks/domain/${domain}`, auth);
- if (!response.data?.ranks?.length) {
- return {
- skipped: `${domain} isn't ranked in the top 1 million sites yet`,
- };
+ const first = await lookup(hostname);
+ if (first.data?.ranks?.length) return first.data;
+ try {
+ const second = await lookup(fallback);
+ if (second.data?.ranks?.length) return second.data;
+ } catch {
+ // Ignore fallback failures (e.g. rate limit) and accept the empty first result
}
- return response.data;
+ return { skipped: `${hostname} isn't ranked in the top 1 million sites yet` };
} catch (error) {
return upstreamError(error, 'Tranco rank lookup');
}
diff --git a/api/subdomains.js b/api/subdomains.js
index 5b03c39..e42b63d 100644
--- a/api/subdomains.js
+++ b/api/subdomains.js
@@ -45,10 +45,15 @@ const subdomainsHandler = async (url) => {
params: { q: `%.${domain}`, output: 'json' },
headers: { Accept: 'application/json' },
});
- const rows = Array.isArray(res.data) ? res.data : [];
- const all = collectSubdomains(rows, domain);
+ if (!Array.isArray(res.data)) {
+ return { error: 'Certificate Transparency lookup returned unexpected data, please retry' };
+ }
+ const all = collectSubdomains(res.data, domain);
if (!all.length) {
- return { skipped: `No subdomains found for ${domain} in Certificate Transparency logs` };
+ return {
+ skipped: `No subdomains found for ${domain} in Certificate Transparency logs`,
+ retryable: true,
+ };
}
return {
domain,
diff --git a/package.json b/package.json
index 073ceed..10d53bc 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,8 @@
"typecheck": "astro check",
"lint": "eslint --config .config/eslint.config.js .",
"format:check": "prettier --check --ignore-unknown '!yarn.lock' '!**/*.md' .",
- "format:fix": "prettier --write --ignore-unknown '!yarn.lock' '!**/*.md' ."
+ "format:fix": "prettier --write --ignore-unknown '!yarn.lock' '!**/*.md' .",
+ "hold-my-beer": "yarn format:fix && yarn lint && yarn typecheck"
},
"dependencies": {
"@astrojs/check": "^0.9.9",
diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png
index 818bfea..126f0fe 100644
Binary files a/public/android-chrome-192x192.png and b/public/android-chrome-192x192.png differ
diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png
index 310e195..35ba8e8 100644
Binary files a/public/android-chrome-512x512.png and b/public/android-chrome-512x512.png differ
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
index b00150d..ee7e75f 100644
Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ
diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png
index 4c7a938..d422a7c 100644
Binary files a/public/favicon-16x16.png and b/public/favicon-16x16.png differ
diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png
index cba0476..8055a30 100644
Binary files a/public/favicon-32x32.png and b/public/favicon-32x32.png differ
diff --git a/public/manifest.json b/public/manifest.json
index 3febec9..4babde7 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -1,20 +1,45 @@
{
+ "name": "Web Check",
"short_name": "Web Check",
- "name": "Lissy93/Web-Check",
+ "description": "Web Check is the all-in-one OSINT and security tool, for revealing the inner workings of any website",
+ "id": "/",
+ "start_url": "/",
+ "scope": "/",
+ "display": "standalone",
+ "theme_color": "#d6fb41",
+ "background_color": "#111211",
"icons": [
{
- "src": "favicon.ico",
- "sizes": "64x64 32x32 24x24 16x16",
- "type": "image/x-icon"
+ "src": "/favicon.svg",
+ "type": "image/svg+xml",
+ "sizes": "any"
},
{
- "src": "apple-touch-icon.png",
+ "src": "/favicon-16x16.png",
+ "type": "image/png",
+ "sizes": "16x16"
+ },
+ {
+ "src": "/favicon-32x32.png",
+ "type": "image/png",
+ "sizes": "32x32"
+ },
+ {
+ "src": "/apple-touch-icon.png",
"type": "image/png",
"sizes": "180x180"
+ },
+ {
+ "src": "/android-chrome-192x192.png",
+ "type": "image/png",
+ "sizes": "192x192",
+ "purpose": "any"
+ },
+ {
+ "src": "/android-chrome-512x512.png",
+ "type": "image/png",
+ "sizes": "512x512",
+ "purpose": "any"
}
- ],
- "start_url": ".",
- "display": "standalone",
- "theme_color": "#9fef00",
- "background_color": "#141d2b"
+ ]
}
diff --git a/src/client/components/Form/Nav.tsx b/src/client/components/Form/Nav.tsx
index 749b8ed..ae96729 100644
--- a/src/client/components/Form/Nav.tsx
+++ b/src/client/components/Form/Nav.tsx
@@ -20,7 +20,7 @@ const Nav = (props: { children?: ReactNode }) => {
return (
-
- Terminal Trove
- {' '}
- - The $HOME of all things in the terminal.
-
+ It's free, open source, and funded by the community. If it's been useful, you can keep it
+ going (and ad-free) by{' '}
+
+ sponsoring me on GitHub
-
+
Web Check
diff --git a/src/client/components/misc/FancyBackground.tsx b/src/client/components/misc/FancyBackground.tsx
index fa9c2d5..5415d69 100644
--- a/src/client/components/misc/FancyBackground.tsx
+++ b/src/client/components/misc/FancyBackground.tsx
@@ -315,12 +315,16 @@ const FancyBackground = (): JSX.Element => {
useEffect(() => {
App.setup();
App.draw();
-
- var frame = function () {
- App.evolve();
+ const frameInterval = 25;
+ let lastTime = 0;
+ const frame = (now: number) => {
+ if (now - lastTime >= frameInterval) {
+ App.evolve();
+ lastTime = now;
+ }
requestAnimationFrame(frame);
};
- frame();
+ requestAnimationFrame(frame);
}, [App]);
return (
diff --git a/src/client/components/misc/Footer.tsx b/src/client/components/misc/Footer.tsx
index fbd97ef..8114890 100644
--- a/src/client/components/misc/Footer.tsx
+++ b/src/client/components/misc/Footer.tsx
@@ -51,7 +51,7 @@ const Footer = (props: { isFixed?: boolean }): JSX.Element => {
Web-Check is licensed under
-
- Get updates on the latest CLI/TUI tools via the{' '}
-
- Terminal Trove newsletter
-
-
-
+