login/ block concurrent login, allow single factor authen for staff and viewer

This commit is contained in:
Thanakorn S
2026-05-25 09:43:30 +07:00
parent b07882e3f4
commit 293097363b
9 changed files with 124 additions and 22 deletions
+25
View File
@@ -253,6 +253,31 @@ if (password_verify(trim($data["password"]), $temp["password"])) {
exit(json_encode($answer));
}
// ── Step 5g: Role check — staff/viewer skip OTP entirely ─────────────────
// Owners always require 2FA. Invited users (license='user') require 2FA only
// if their role in this company is admin or owner; staff/viewer go straight in.
$requires_otp = true;
if (($r['license'] ?? 'owner') !== 'owner') {
$sth_role = $pdo1->prepare(
"SELECT role FROM company_map_user WHERE company_id = :cid AND user_id = :uid LIMIT 1"
);
$sth_role->execute([':cid' => (int)($r['default_company'] ?? 0), ':uid' => (int)$r['user_id']]);
$role_for_otp = ($sth_role->fetch(PDO::FETCH_ASSOC))['role'] ?? 'viewer';
$requires_otp = in_array($role_for_otp, ['admin', 'owner'], true);
}
if (!$requires_otp) {
$_SESSION = [];
$_SESSION['login_data'] = $data;
$_SESSION['login_user_id'] = $user_id;
$_SESSION['otpTime'] = time();
$_SESSION['skip_otp'] = true;
$answer['success'] = 1;
$answer['skip_otp'] = true;
$answer['message'] = 'Login Complete!';
exit(json_encode($answer));
}
// ── Step 6: Generate 6-digit TOTP ────────────────────────────────────────
// The secret key is the user's current password hash, so the OTP is unique
// per user and automatically invalidated if the password changes.