SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
1.6 KB · 29 lines typescript
Raw Blame History
1/** Client-safe password strength estimate (no deps). Returns 0–4 and a reason. */2const COMMON = new Set(['password', 'password1', 'qwerty', '123456', '12345678', 'iloveyou', 'letmein', 'welcome', 'admin', 'rareindex', 'collectibles', 'charizard', 'pokemon']);34export interface Strength {5  score: 0 | 1 | 2 | 3 | 4;6  label: 'Too weak' | 'Weak' | 'Fair' | 'Strong' | 'Excellent';7  hint: string | null;8}910export function passwordStrength(pw: string, email?: string): Strength {11  const s = pw ?? '';12  if (s.length < 10) return { score: 0, label: 'Too weak', hint: 'Use at least 10 characters.' };13  const lower = s.toLowerCase();14  const stem = lower.replace(/[\d!@#$%^&*._-]+$/, '');15  if (COMMON.has(lower) || COMMON.has(stem) || /^(.)\1+$/.test(s) || /^(?:0123456789|1234567890|abcdefghij)/.test(lower)) return { score: 0, label: 'Too weak', hint: 'That password is too common.' };16  if (email && lower.includes(email.split('@')[0]!.toLowerCase()) && email.split('@')[0]!.length >= 4) return { score: 1, label: 'Weak', hint: 'Avoid using your e-mail in the password.' };17  let pool = 0;18  if (/[a-z]/.test(s)) pool += 26;19  if (/[A-Z]/.test(s)) pool += 26;20  if (/\d/.test(s)) pool += 10;21  if (/[^A-Za-z0-9]/.test(s)) pool += 33;22  const uniq = new Set(s).size;23  const entropy = Math.log2(pool || 1) * s.length * Math.min(1, uniq / 6);24  if (entropy < 45) return { score: 1, label: 'Weak', hint: 'Add more variety or length.' };25  if (entropy < 60) return { score: 2, label: 'Fair', hint: 'A passphrase of 4+ words is stronger.' };26  if (entropy < 80) return { score: 3, label: 'Strong', hint: null };27  return { score: 4, label: 'Excellent', hint: null };28}29