false, "message" => "Username/password missing"]); exit; } try { [$pdo, $tmpDb, $lockFp] = qdb_open(false); $stmt = $pdo->prepare( "SELECT userID, passwordHash, role, entityID, mustChangePassword FROM users WHERE username = :u" ); $stmt->execute([':u' => $username]); $user = $stmt->fetch(PDO::FETCH_ASSOC); $pdo = null; qdb_discard($tmpDb, $lockFp); if (!$user) { http_response_code(401); echo json_encode(["success" => false, "message" => "Invalid credentials"]); exit; } if (!password_verify($password, $user['passwordHash'])) { http_response_code(401); echo json_encode(["success" => false, "message" => "Invalid credentials"]); exit; } if ((int)$user['mustChangePassword'] === 1) { $tempToken = bin2hex(random_bytes(32)); token_add($tempToken, 10 * 60, [ 'role' => $user['role'], 'entityID' => $user['entityID'], 'userID' => $user['userID'], 'temp' => true, ]); echo json_encode([ "success" => true, "user" => $username, "role" => $user['role'], "must_change_password" => true, "temp_token" => $tempToken, "message" => "Please change your password." ]); exit; } $token = bin2hex(random_bytes(32)); token_add($token, 30 * 24 * 60 * 60, [ 'role' => $user['role'], 'entityID' => $user['entityID'], 'userID' => $user['userID'], ]); echo json_encode([ "success" => true, "token" => $token, "user" => $username, "role" => $user['role'], ]); } catch (Throwable $e) { http_response_code(500); echo json_encode(["success" => false, "message" => "Server error"]); }