From 74380a3176d2366cf24fd02416bf94334f6fa1d0 Mon Sep 17 00:00:00 2001 From: Jukka Lampikoski Date: Fri, 13 Mar 2026 02:26:16 +0200 Subject: [PATCH] Saatavuuskyselyt: IP/hostname, duplikaattien esto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reverse DNS -haku tallentaa hostnamen IP:n rinnalle (paljastaa operaattorin ja alueen, esim. dsl-hel-123.elisa.fi) - Duplikaattikyselyn (sama osoite+postinumero+kaupunki) ei tallenneta uudelleen samalle yritykselle - IP/hostname -sarake lisätty taulukkoon Co-Authored-By: Claude Opus 4.6 --- api.php | 45 +++++++++++++++++++++++++++++---------------- db.php | 1 + index.html | 5 +++-- script.js | 6 +++++- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/api.php b/api.php index 0a07f68..24459e7 100644 --- a/api.php +++ b/api.php @@ -1215,23 +1215,36 @@ switch ($action) { } } - // Tallenna kysely tietokantaan + // Tallenna kysely tietokantaan (ohita duplikaatit: sama osoite+postinumero+kaupunki+yritys) try { - _dbExecute( - "INSERT INTO availability_queries (company_id, osoite, postinumero, kaupunki, saatavilla, ip_address, user_agent, referer, created_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", - [ - $matchedCompany['id'], - $_GET['osoite'] ?? '', - $_GET['postinumero'] ?? '', - $_GET['kaupunki'] ?? '', - $found ? 1 : 0, - getClientIp(), - substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 500), - substr($_SERVER['HTTP_REFERER'] ?? '', 0, 500), - date('Y-m-d H:i:s'), - ] + $rawOsoite = $_GET['osoite'] ?? ''; + $rawPostinumero = $_GET['postinumero'] ?? ''; + $rawKaupunki = $_GET['kaupunki'] ?? ''; + $exists = _dbFetchScalar( + "SELECT COUNT(*) FROM availability_queries WHERE company_id = ? AND LOWER(osoite) = LOWER(?) AND postinumero = ? AND LOWER(kaupunki) = LOWER(?)", + [$matchedCompany['id'], $rawOsoite, $rawPostinumero, $rawKaupunki] ); + if (!$exists) { + $ip = getClientIp(); + $hostname = @gethostbyaddr($ip) ?: ''; + if ($hostname === $ip) $hostname = ''; // gethostbyaddr palauttaa IP:n jos ei löydy + _dbExecute( + "INSERT INTO availability_queries (company_id, osoite, postinumero, kaupunki, saatavilla, ip_address, hostname, user_agent, referer, created_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + [ + $matchedCompany['id'], + $rawOsoite, + $rawPostinumero, + $rawKaupunki, + $found ? 1 : 0, + $ip, + $hostname, + substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 500), + substr($_SERVER['HTTP_REFERER'] ?? '', 0, 500), + date('Y-m-d H:i:s'), + ] + ); + } } catch (\Throwable $e) { /* logitus ei saa kaataa API-vastausta */ } echo json_encode(['saatavilla' => $found]); @@ -1254,7 +1267,7 @@ switch ($action) { $total = (int)_dbFetchScalar("SELECT COUNT(*) FROM availability_queries WHERE company_id IN ($placeholders)", $userCompanyIds); $params = array_merge($userCompanyIds, [$limit, $offset]); $rows = _dbFetchAll( - "SELECT aq.id, aq.company_id, c.nimi as company_nimi, aq.osoite, aq.postinumero, aq.kaupunki, aq.saatavilla, aq.ip_address, aq.referer, aq.created_at + "SELECT aq.id, aq.company_id, c.nimi as company_nimi, aq.osoite, aq.postinumero, aq.kaupunki, aq.saatavilla, aq.ip_address, aq.hostname, aq.referer, aq.created_at FROM availability_queries aq LEFT JOIN companies c ON c.id = aq.company_id WHERE aq.company_id IN ($placeholders) ORDER BY aq.created_at DESC LIMIT ? OFFSET ?", $params diff --git a/db.php b/db.php index 55bd96e..2764390 100644 --- a/db.php +++ b/db.php @@ -675,6 +675,7 @@ function initDatabase(): void { "ALTER TABLE ticket_rules ADD COLUMN set_tags VARCHAR(255) DEFAULT '' AFTER set_priority", "ALTER TABLE tickets ADD COLUMN zammad_ticket_id INT DEFAULT NULL AFTER mailbox_id", "ALTER TABLE ticket_messages ADD COLUMN zammad_article_id INT DEFAULT NULL AFTER message_id", + "ALTER TABLE availability_queries ADD COLUMN hostname VARCHAR(255) DEFAULT '' AFTER ip_address", ]; foreach ($alters as $sql) { try { $db->query($sql); } catch (\Throwable $e) { /* sarake on jo olemassa / jo ajettu */ } diff --git a/index.html b/index.html index 8da7295..fd7d19d 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ Noxus HUB - + @@ -209,6 +209,7 @@ Postinumero Kaupunki Tulos + IP / Verkko Lähde Yritys @@ -2263,6 +2264,6 @@ - + diff --git a/script.js b/script.js index a60f8f4..e983f0c 100644 --- a/script.js +++ b/script.js @@ -3520,7 +3520,7 @@ async function loadAvailabilityQueries(page = 0) { countEl.textContent = `Yhteensä ${data.total} kyselyä`; if (data.queries.length === 0) { - tbody.innerHTML = 'Ei vielä kyselyjä'; + tbody.innerHTML = 'Ei vielä kyselyjä'; } else { tbody.innerHTML = data.queries.map(q => { const date = q.created_at ? q.created_at.replace('T', ' ').substring(0, 16) : ''; @@ -3532,12 +3532,16 @@ async function loadAvailabilityQueries(page = 0) { if (q.referer) { try { source = new URL(q.referer).hostname; } catch(e) { source = q.referer.substring(0, 30); } } + const ipInfo = q.hostname + ? `${esc(q.ip_address)}
${esc(q.hostname)}` + : esc(q.ip_address || ''); return ` ${esc(date)} ${esc(q.osoite)} ${esc(q.postinumero)} ${esc(q.kaupunki)} ${badge} + ${ipInfo} ${esc(source)} ${esc(q.company_nimi || q.company_id || '')} `;