[ {"fn": "passwordChecklist", "name": "a password meeting NIST's single-factor policy ticks every rule", "args": [{"name": "nist-800-63b-4-single-factor", "minLength": 15, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, {"valid": true, "failures": []}], "expect": [{"rule": "too_short", "text": "At least 15 characters", "met": true}, {"rule": "too_long", "text": "No more than 128 characters", "met": true}, {"rule": "too_common", "text": "Not a commonly used password", "met": true}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": true}]}, {"fn": "passwordChecklist", "name": "too short is the first rule unmet", "args": [{"name": "nist-800-63b-4-single-factor", "minLength": 15, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, {"valid": false, "failures": [{"code": "too_short", "message": "Use at least 15 characters."}]}], "expect": [{"rule": "too_short", "text": "At least 15 characters", "met": false}, {"rule": "too_long", "text": "No more than 128 characters", "met": true}, {"rule": "too_common", "text": "Not a commonly used password", "met": true}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": true}]}, {"fn": "passwordChecklist", "name": "too short and too common, both unmet", "args": [{"name": "nist-800-63b-4-multi-factor", "minLength": 8, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, {"valid": false, "failures": [{"code": "too_short", "message": "Use at least 8 characters."}, {"code": "too_common", "message": "This password is too common. Choose something harder to guess."}]}], "expect": [{"rule": "too_short", "text": "At least 8 characters", "met": false}, {"rule": "too_long", "text": "No more than 128 characters", "met": true}, {"rule": "too_common", "text": "Not a commonly used password", "met": false}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": true}]}, {"fn": "passwordChecklist", "name": "the email and the name are separate rules", "args": [{"name": "nist-800-63b-4-single-factor", "minLength": 15, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, {"valid": false, "failures": [{"code": "contains_email", "message": "Do not include your email address in your password."}, {"code": "contains_name", "message": "Do not include your name in your password."}]}], "expect": [{"rule": "too_short", "text": "At least 15 characters", "met": true}, {"rule": "too_long", "text": "No more than 128 characters", "met": true}, {"rule": "too_common", "text": "Not a commonly used password", "met": true}, {"rule": "contains_email", "text": "Does not include your email address", "met": false}, {"rule": "contains_name", "text": "Does not include your name", "met": false}]}, {"fn": "passwordChecklist", "name": "only the name is in the password", "args": [{"name": "nist-800-63b-4-multi-factor", "minLength": 8, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, {"valid": false, "failures": [{"code": "contains_name", "message": "Do not include your name in your password."}]}], "expect": [{"rule": "too_short", "text": "At least 8 characters", "met": true}, {"rule": "too_long", "text": "No more than 128 characters", "met": true}, {"rule": "too_common", "text": "Not a commonly used password", "met": true}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": false}]}, {"fn": "passwordChecklist", "name": "over the maximum length", "args": [{"name": "nist-800-63b-4-multi-factor", "minLength": 8, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, {"valid": false, "failures": [{"code": "too_long", "message": "Use no more than 128 characters."}]}], "expect": [{"rule": "too_short", "text": "At least 8 characters", "met": true}, {"rule": "too_long", "text": "No more than 128 characters", "met": false}, {"rule": "too_common", "text": "Not a commonly used password", "met": true}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": true}]}, {"fn": "passwordChecklist", "name": "a composition policy lists its character classes, after the lengths", "args": [{"name": "composition-12-3", "minLength": 12, "maxLength": 128, "minCharacterClasses": 3, "blockCommon": true, "blockPersonal": true}, {"valid": false, "failures": [{"code": "too_few_character_classes", "message": "Use at least 3 of these: lower-case letters, capital letters, digits, symbols."}, {"code": "too_common", "message": "This password is too common. Choose something harder to guess."}]}], "expect": [{"rule": "too_short", "text": "At least 12 characters", "met": true}, {"rule": "too_long", "text": "No more than 128 characters", "met": true}, {"rule": "too_few_character_classes", "text": "At least 3 of: lower-case letters, capital letters, digits, symbols", "met": false}, {"rule": "too_common", "text": "Not a commonly used password", "met": false}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": true}]}, {"fn": "passwordChecklist", "name": "a policy without a blocklist or personal words lists only the lengths, a minimum of 1 in the singular", "args": [{"name": "pin", "minLength": 1, "maxLength": 64, "minCharacterClasses": 0, "blockCommon": false, "blockPersonal": false}, {"valid": true, "failures": []}], "expect": [{"rule": "too_short", "text": "At least 1 character", "met": true}, {"rule": "too_long", "text": "No more than 64 characters", "met": true}]}, {"fn": "passwordChecklist", "name": "one character class, no blocklist, personal words refused", "args": [{"name": "personal-only", "minLength": 10, "maxLength": 64, "minCharacterClasses": 1, "blockCommon": false, "blockPersonal": true}, {"valid": false, "failures": [{"code": "too_short", "message": "Use at least 10 characters."}]}], "expect": [{"rule": "too_short", "text": "At least 10 characters", "met": false}, {"rule": "too_long", "text": "No more than 64 characters", "met": true}, {"rule": "too_few_character_classes", "text": "At least 1 of: lower-case letters, capital letters, digits, symbols", "met": true}, {"rule": "contains_email", "text": "Does not include your email address", "met": true}, {"rule": "contains_name", "text": "Does not include your name", "met": true}]}, {"fn": "passwordChecklist", "name": "a failure the policy has no rule for is not listed", "args": [{"name": "common-only", "minLength": 8, "maxLength": 8, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": false}, {"valid": false, "failures": [{"code": "contains_name", "message": "Do not include your name in your password."}]}], "expect": [{"rule": "too_short", "text": "At least 8 characters", "met": true}, {"rule": "too_long", "text": "No more than 8 characters", "met": true}, {"rule": "too_common", "text": "Not a commonly used password", "met": true}]}, {"fn": "PasswordField", "name": "signing in: hidden, no spell check or capitals, current-password, and the Show button hidden until it can work", "args": [{"id": "password", "label": "Password"}], "expect": "
"}, {"fn": "PasswordField", "name": "choosing a password without a policy: new-password, with a hint", "args": [{"id": "new", "label": "Create a password", "hint": "Use 15 characters or more", "autoComplete": "new-password"}], "expect": "
Use 15 characters or more
"}, {"fn": "PasswordField", "name": "an error marks the input invalid and describes it", "args": [{"id": "password", "label": "Password", "error": "Enter your password"}], "expect": "

Error: Enter your password

"}, {"fn": "PasswordField", "name": "a name of its own; required and disabled, and the button disabled with it", "args": [{"id": "pw", "name": "password", "label": "Password", "required": true, "disabled": true}], "expect": "
"}, {"fn": "PasswordField", "name": "a controlled value is written last, escaped", "args": [{"id": "pw", "label": "Password", "value": "a&b\"c"}], "expect": "
"}, {"fn": "PasswordField", "name": "a policy adds a checklist that describes the input, and makes it new-password; empty is only too short", "args": [{"id": "pw", "label": "Create a password", "policy": {"name": "nist-800-63b-4-multi-factor", "minLength": 8, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, "defaultValue": ""}], "expect": "
"}, {"fn": "PasswordField", "name": "the checklist follows the typed password: the email's local part and the name are both in it", "args": [{"id": "pw", "label": "Create a password", "hint": "Use a long passphrase", "policy": {"name": "nist-800-63b-4-single-factor", "minLength": 15, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, "email": "ada.lovelace@example.com", "personName": "Ada Lovelace", "value": "lovelacebatteryhorse"}], "expect": "
Use a long passphrase
"}, {"fn": "PasswordField", "name": "a composition policy: twelve characters, but two classes and on the common list", "args": [{"id": "pw", "label": "New password", "policy": {"name": "composition-12-3", "minLength": 12, "maxLength": 128, "minCharacterClasses": 3, "blockCommon": true, "blockPersonal": true}, "value": "q1w2e3r4t5y6"}], "expect": "
"}, {"fn": "PasswordField", "name": "an error, a policy and a class together: described by the error then the checklist", "args": [{"id": "pw", "label": "Password", "error": "Choose a longer password", "policy": {"name": "nist-800-63b-4-multi-factor", "minLength": 8, "maxLength": 128, "minCharacterClasses": 0, "blockCommon": true, "blockPersonal": true}, "value": "short", "className": "wide", "autoComplete": "new-password"}], "expect": "

Error: Choose a longer password

"}, {"fn": "PasswordField", "name": "the label is escaped", "args": [{"id": "p", "label": "Password & PIN"}], "expect": "
"}, {"fn": "PasswordField", "name": "an id with a space is refused", "args": [{"id": "my password", "label": "Password"}], "expectError": "a field id cannot contain spaces"}, {"fn": "PasswordField", "name": "a policy with a minimum of 0 is refused by checkPassword", "args": [{"id": "pw", "label": "Password", "policy": {"name": "broken", "minLength": 0, "maxLength": 10, "minCharacterClasses": 0, "blockCommon": false, "blockPersonal": false}}], "expectError": "policy minLength must be a whole number of at least 1"} ]