// Four segments saying how much a password has going for it. // // The score is computed here, from length and which character classes appear, // and from nothing else. There is no dictionary, no breach list and no network // call, so the row claims exactly what it can back up: it is headed "Strength" // and says in its own detail line that it only measures shape. A meter that // says "Strong" about a leaked password is worse than no meter, so this one // never uses that word. import QtQuick import qs.config SettingRow { id: root property string password: "" readonly property int score: { const value = root.password; if (value === "") return 0; let classes = 0; if (/[a-z]/.test(value)) classes += 1; if (/[A-Z]/.test(value)) classes += 1; if (/[0-9]/.test(value)) classes += 1; if (/[^A-Za-z0-9]/.test(value)) classes += 1; let points = Math.max(0, classes - 1); if (value.length >= 8) points += 1; if (value.length >= 12) points += 1; if (value.length >= 16) points += 1; if (value.length < 8) return 1; return Math.max(1, Math.min(4, points)); } readonly property color tone: { if (root.score <= 1) return Theme.danger; if (root.score === 2) return Theme.warn; return Theme.ok; } label: "Strength" detail: "Length and variety of characters, measured here — nothing is sent anywhere, and nothing is checked against known passwords" controlWidth: 150 Row { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: 5 Repeater { model: 4 delegate: Rectangle { required property int index width: 32 height: 5 radius: 2.5 color: index < root.score ? root.tone : Theme.alpha(Theme.fg, 0.12) border.width: 0 } } } }