# Overview.Admin

## What it does

Password Policy applies shared password rules to Capell admin users. It can enforce length and complexity, reject compromised or recently used passwords, expire old passwords, warn users before expiry, and require selected users to change their password before continuing in the admin.

## Where it shows up

Open **System > Password Policy** to configure the rules. Access to that settings page requires `Manage:PasswordPolicySettingsPage`.

When **Force password change** is enabled, the Users table gains password-policy columns, filters, and single/bulk **Require password change** actions for users the operator is allowed to update. A flagged or expired user is redirected to a private password-change page after signing in and can otherwise only sign out until the password is changed.

## Configure the policy

- Set a minimum length of at least eight characters and optionally require mixed case, numbers, and symbols.
- **Compromised password checks** reject passwords reported by Laravel's uncompromised-password service. Password changes therefore need working outbound access to that service when this option is enabled.
- **Password history** rejects the configured number of recently used password hashes. Run the package migrations before enabling it; Diagnostics reports a failure if history is enabled without its table.
- **Password expiry** compares each recorded password-change time with the configured age. Existing users with no recorded change time are not treated as expired solely because expiry was enabled.
- **Expiry warning notifications** use the configured warning window and are sent once per password change.

Strength, compromised-password, and history rules are evaluated when a password is created or changed; they do not prove that existing password hashes meet the new rules. Expiry does apply to existing users that have a recorded password-change time.

The package wires these checks into Capell's Filament user create/edit form and its forced-change page. A custom registration, password-reset, API, or other password-writing flow must call the package validation/update boundary itself; do not assume installing the package automatically covers an unrelated host flow.

## Force changes and recover access

Enable **Force password change** before marking users. Use the action on the Users table for normal administration, or `capell:password-policy:require-change --user-id=<id>` for one user. The `--all` option affects every user, so run it with `--dry-run` first and only use it during a planned rollout.

A successful change verifies the current password, applies the current policy, records the previous hash for history checks, clears the force-change flag and notification markers, and records the new change time. If users loop back to the change page, run `capell:password-policy:doctor` and check the user columns and settings migrations.

## Scheduling and maintenance

The package provides maintenance commands but does not add them to Laravel's scheduler. The host application must schedule the work it needs and keep both the scheduler and queue worker running:

- `capell:password-policy:send-expiry-warnings` finds users inside the warning window and queues their email notifications. Without a queue worker, the emails remain pending.
- `capell:password-policy:expire-stale` can proactively flag users whose recorded password age exceeds the policy. Runtime middleware also checks expiry when an authenticated admin request is made.
- `capell:password-policy:prune-history` removes older history rows while retaining the configured or explicitly requested number per user. Use `--dry-run` before changing retained history.

Changing or disabling the policy does not delete password-history rows automatically. Choose a maintenance cadence that matches the site's account lifecycle and audit requirements.