3 Commits
Author SHA1 Message Date
Nic Boet b631d2efc9 feat: add a minimum length for new passwords refs #5287
Add ZM_PASSWORD_MIN_LENGTH (Options, System; default 8, 0 turns it off).
passwordProblem() refuses a shorter password, so the user page, the API
and both login-page forms apply it alike. Existing passwords keep
working; only a password being set is checked. The length counts
characters, not bytes.

There is no setting for character classes: they push people to
predictable variations (Password1!) and add less than length does.

A database whose Config table doesn't have the option yet (an upgrade
not run with zmupdate.pl -f) gets no minimum. The password inputs carry
minlength so the browser says so before the form is sent; the server
check is the one that counts. The API answers with the English text, as
for the other reasons.

Tests: tests/php/test_default_password.php.
2026-10-16 10:13:53 -05:00
Nic Boet fd93780425 fix: refuse the password admin wherever a password is set refs #5287
The login page's change form and the first-run page refused admin as a
new password, but the user page (Options, Users, and a user's own page
with ZM_USER_SELF_EDIT) and the API (users/add, users/edit) still stored
it. Every login then refused that account.

Check a new password in one place, passwordProblem() in auth.php, and
call it from all four:

- includes/actions/user.php, for an admin's edit and a self edit: the
  save stops with the reason shown on the page. A Password sent as an
  array is refused too (it reached password_hash() before).
- api/app/Model/User.php: an "acceptable" validation rule, so add and
  edit answer with the reason as the validation message. The API loads
  no language file, so passwordProblemText() gives it the English.
- newPasswordProblem() (both login-page forms) checks the confirmation,
  then passwordProblem().

Tests: tests/php/test_default_password.php covers passwordProblem() and
passwordProblemText().
2026-10-16 10:12:53 -05:00
Nic Boet ebbe1e59e2 feat: ask on the first page whether to require a login refs #5287
A new install starts with authentication on and the admin password admin,
which is refused everywhere. Asking for that password just to replace it is
an extra step, and some installs don't want a login at all. Ask instead.

While the first run is pending (authentication on, the privacy page not
answered yet, builtin auth, and admin still has the password admin), the
login page shows "Set up ZoneMinder" instead of the login form:

- Require a login: choose the admin password; the account is then logged
  in and the privacy page follows, as before.
- Don't require a login: ZM_OPT_USE_AUTH is set to 0 in the database.
  Not offered when ZM_OPT_USE_AUTH is set in zm.conf or conf.d: the owner
  of the box has decided then, and only the password is asked for.

Until one is chosen the web interface, API and streams can't be used: the
password admin is still refused. Whoever opens the page first makes the
choice; before this, whoever typed admin/admin did. The form carries a
nonce kept in the session, like the default-password form, and is exempt
from csrf-magic as action=login is (the login regenerates the session id).
Both choices are audited. Upgrades are not affected: ZM_SHOW_PRIVACY is 0
once the privacy page was answered, and zmupdate.pl doesn't reset it.

Docs: a First Run section in the getting-started guide, and the FAQ and
system options updated to match.

Tests: tests/php/test_first_run.php.
2026-10-16 10:10:25 -05:00