Issue #3594912: Make the vault unlock duration configurable per tenant, with a sliding idle timeout
Replaces the hardcoded 30-minute unlock backstop with a configurable, sliding idle timeout.
Problem
A passphrase-unlocked vault auto-locked after a fixed 30 minutes regardless of activity, while the unlock form promises "for this session".
Resolution
- Per-tenant
unlock_ttlplus a site-wide default (pdv.settings:unlock_ttl, shipped 1800).VaultSessionresolves the tenant value, else the site default, else a positive backstop (no "stay unlocked forever"). - Idle timeout that slides with activity:
rehydrate()re-extends the window, throttled past the halfway mark (no write on every request), so an active owner stays unlocked while an idle one re-locks afterunlock_ttl. Closing the browser still locks at once (session cookie). - A "Stay unlocked for" field on the tenant add/edit form and the site-wide default on the PDV settings form.
Tests
New kernel coverage (VaultUnlockTtlTest): tenant override, inherit-default, positive backstop, sliding-near-expiry, no-slide-when-ample. phpcs + phpstan clean; existing session/unlock/tenant suites still pass.