Harden sign-in and password reset

- OTP attempt limits, constant-time compare, random reference codes
- DB-backed rate limits (429) on sign-in, OTP, reset, register, onboarding
- one generic sign-in failure message; reset request no longer reveals accounts
- no password kept in the session; real status codes on failures
This commit is contained in:
Thanakorn
2026-09-24 14:53:40 +07:00
parent ae98dcdcdd
commit 73c680e844
16 changed files with 538 additions and 282 deletions
+10 -2
View File
@@ -1,8 +1,16 @@
<?php
// Profile page "Forgot your current password?" — signed-in users only.
// (This used to declare UNAUTHENTICATED_ROUTE, which let anonymous callers in
// with no $user_id; the login page has its own endpoint in login/api/engine/.)
require_once __DIR__ . '/../../../session.php';
define('UNAUTHENTICATED_ROUTE', true);
require_once '../../../assets/utils/db_auth.php';
require_once '../../../assets/utils/rate_limit.php';
require_once '../../../assets/utils/classes/PasswordResetManager.php';
// Every hit sends an email.
rate_limit_guard($pdo1, [
['reset_req_user', (string)$user_id, 3, 900],
]);
$prm = new PasswordResetManager($pdo1, $pdo2, $include_url, $SMTP, $pinkey);
$prm->handleRequestOtp($user_id, $company_id);
$prm->handleRequestOtp($user_id, $company_id);