Privacy Score — JavaScript source
One number for your privacy health: your browser fingerprint, a test password's strength and breach exposure, and a site's security headers — four checks, one score, concrete fixes. Runs in your browser; only a 5-character hash prefix ever leaves it.
This is the JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.
// privacy-score — composite privacy scoring engine.
//
// Language: JavaScript (ES2020, no dependencies)
// Source: CosmoDev polyglot showcase port of the Privacy Score tool,
// ported from src/lib/privacy-score.ts (canonical TypeScript).
// License: display source — part of CosmoDev's polyglot tool pages.
//
// Four category checks, each scored out of 25; the overall percent is
// renormalized over the categories that actually ran — skipping a check
// never lowers your score. Letter bands: >=85 A, >=70 B, >=50 C, else D.
const clamp25 = (points) => Math.max(0, Math.min(25, Math.round(points)));
const statusFor = (points) => (points >= 20 ? 'ok' : points >= 10 ? 'warn' : 'bad');
// More distinguishable signals make a browser more unique: high-risk
// signals cost 4 each, medium 1.5, and a large surface costs a little more.
function fingerprintPoints(signalCount, highRiskCount, mediumRiskCount) {
const surface = Math.max(0, signalCount - 12) * 0.5;
return clamp25(25 - highRiskCount * 4 - mediumRiskCount * 1.5 - surface);
}
function passwordPoints(score, breached) {
const base = (Math.max(0, Math.min(4, score)) / 4) * 25;
// Breached is urgent regardless of strength: x0.32 floors even a
// score-4 password at 8 points -> 'bad' -> the change-it recommendation.
return clamp25(breached ? base * 0.32 : base);
}
function headersPoints(grades) {
const counts = { A: 0, B: 0, C: 0, F: 0 };
for (const g of grades) if (g in counts) counts[g]++;
if (counts.F > 0) return 0;
if (counts.C > 0) return 10;
if (counts.B > 0) return 18;
return grades.length > 0 ? 25 : 0;
}
const breachPoints = (pwned) => (pwned ? 0 : 25);
function letterFor(percent, max) {
if (max === 0) return '—';
if (percent >= 85) return 'A';
if (percent >= 70) return 'B';
if (percent >= 50) return 'C';
return 'D';
}
// Renormalize over the checks that ran and grade the overall letter.
function scorePrivacy(points) {
const total = points.reduce((a, p) => a + p, 0);
const max = points.length * 25;
const percent = max === 0 ? 0 : Math.round((total / max) * 100);
return {
total,
max,
percent,
letter: letterFor(percent, max),
statuses: points.map(statusFor),
};
}
const checks = [
fingerprintPoints(18, 2, 4), // 8
passwordPoints(4, true), // 8 (breach floor)
headersPoints(['A', 'A', 'B']), // 18
breachPoints(false), // 25
];
console.log(checks);
console.log(scorePrivacy(checks));
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →