- Hash driver read from HASH_DRIVER (argon2id in production); bcrypt
hashes still verify and are rehashed on successful admin/client login
since the JWT guard and guard->validate() never rehash on their own.
- Client registration uses Hash::make instead of bcrypt(), which always
forced bcrypt regardless of the configured driver.
- SignRSA now encrypts with Crypt (AES-256-CBC + HMAC, APP_KEY) instead
of 3DES in ECB mode without IV. Legacy 3DES values are still readable
via RSA_KEY/RSA_PUBLIC until `secrets:reencrypt` migrates them;
RSA_PRIVATE is no longer used.
- LegacyPortalImporter stored module_vmware.password in plaintext; it is
now encrypted, and a migration encrypts existing plaintext rows.
Deploy: php artisan migrate, then secrets:reencrypt --dry-run and
secrets:reencrypt; remove RSA_* from env once it exits 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Turnstile (App\Support\Turnstile, middleware turnstile) cho login admin và login/register/forgot/reset của khách; cấu hình ở setting key=turnstile, secret mã hoá SignRSA.
- Menu sidebar khách (setting client_menu) và nút tắt topbar (setting client_quick_links) do admin sửa qua administrator/client-menu[/quick-links], khách đọc v1/setting/menu, v1/setting/quick-links.
- v1/setting và settings/public chỉ trả whitelist PublicSetting::FIELDS (trước đây lộ bot_token, inet_api_key).
- Cài đặt tài khoản khách (preferences), rate limit theo IP cho register/resend-verify.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>