Saatavuuskyselyt: IP/hostname, duplikaattien esto
- 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 <noreply@anthropic.com>
This commit is contained in:
45
api.php
45
api.php
@@ -1215,23 +1215,36 @@ switch ($action) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tallenna kysely tietokantaan
|
// Tallenna kysely tietokantaan (ohita duplikaatit: sama osoite+postinumero+kaupunki+yritys)
|
||||||
try {
|
try {
|
||||||
_dbExecute(
|
$rawOsoite = $_GET['osoite'] ?? '';
|
||||||
"INSERT INTO availability_queries (company_id, osoite, postinumero, kaupunki, saatavilla, ip_address, user_agent, referer, created_at)
|
$rawPostinumero = $_GET['postinumero'] ?? '';
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
$rawKaupunki = $_GET['kaupunki'] ?? '';
|
||||||
[
|
$exists = _dbFetchScalar(
|
||||||
$matchedCompany['id'],
|
"SELECT COUNT(*) FROM availability_queries WHERE company_id = ? AND LOWER(osoite) = LOWER(?) AND postinumero = ? AND LOWER(kaupunki) = LOWER(?)",
|
||||||
$_GET['osoite'] ?? '',
|
[$matchedCompany['id'], $rawOsoite, $rawPostinumero, $rawKaupunki]
|
||||||
$_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'),
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
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 */ }
|
} catch (\Throwable $e) { /* logitus ei saa kaataa API-vastausta */ }
|
||||||
|
|
||||||
echo json_encode(['saatavilla' => $found]);
|
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);
|
$total = (int)_dbFetchScalar("SELECT COUNT(*) FROM availability_queries WHERE company_id IN ($placeholders)", $userCompanyIds);
|
||||||
$params = array_merge($userCompanyIds, [$limit, $offset]);
|
$params = array_merge($userCompanyIds, [$limit, $offset]);
|
||||||
$rows = _dbFetchAll(
|
$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
|
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 ?",
|
WHERE aq.company_id IN ($placeholders) ORDER BY aq.created_at DESC LIMIT ? OFFSET ?",
|
||||||
$params
|
$params
|
||||||
|
|||||||
1
db.php
1
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 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 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 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) {
|
foreach ($alters as $sql) {
|
||||||
try { $db->query($sql); } catch (\Throwable $e) { /* sarake on jo olemassa / jo ajettu */ }
|
try { $db->query($sql); } catch (\Throwable $e) { /* sarake on jo olemassa / jo ajettu */ }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Noxus HUB</title>
|
<title>Noxus HUB</title>
|
||||||
<link rel="stylesheet" href="style.css?v=20260313k">
|
<link rel="stylesheet" href="style.css?v=20260313m">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Login -->
|
<!-- Login -->
|
||||||
@@ -209,6 +209,7 @@
|
|||||||
<th>Postinumero</th>
|
<th>Postinumero</th>
|
||||||
<th>Kaupunki</th>
|
<th>Kaupunki</th>
|
||||||
<th>Tulos</th>
|
<th>Tulos</th>
|
||||||
|
<th>IP / Verkko</th>
|
||||||
<th>Lähde</th>
|
<th>Lähde</th>
|
||||||
<th>Yritys</th>
|
<th>Yritys</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -2263,6 +2264,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="script.js?v=20260313k"></script>
|
<script src="script.js?v=20260313m"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3520,7 +3520,7 @@ async function loadAvailabilityQueries(page = 0) {
|
|||||||
countEl.textContent = `Yhteensä ${data.total} kyselyä`;
|
countEl.textContent = `Yhteensä ${data.total} kyselyä`;
|
||||||
|
|
||||||
if (data.queries.length === 0) {
|
if (data.queries.length === 0) {
|
||||||
tbody.innerHTML = '<tr><td colspan="7" style="text-align:center;color:#888;padding:2rem;">Ei vielä kyselyjä</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="8" style="text-align:center;color:#888;padding:2rem;">Ei vielä kyselyjä</td></tr>';
|
||||||
} else {
|
} else {
|
||||||
tbody.innerHTML = data.queries.map(q => {
|
tbody.innerHTML = data.queries.map(q => {
|
||||||
const date = q.created_at ? q.created_at.replace('T', ' ').substring(0, 16) : '';
|
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) {
|
if (q.referer) {
|
||||||
try { source = new URL(q.referer).hostname; } catch(e) { source = q.referer.substring(0, 30); }
|
try { source = new URL(q.referer).hostname; } catch(e) { source = q.referer.substring(0, 30); }
|
||||||
}
|
}
|
||||||
|
const ipInfo = q.hostname
|
||||||
|
? `${esc(q.ip_address)}<br><small style="color:#aaa;">${esc(q.hostname)}</small>`
|
||||||
|
: esc(q.ip_address || '');
|
||||||
return `<tr>
|
return `<tr>
|
||||||
<td style="white-space:nowrap;">${esc(date)}</td>
|
<td style="white-space:nowrap;">${esc(date)}</td>
|
||||||
<td>${esc(q.osoite)}</td>
|
<td>${esc(q.osoite)}</td>
|
||||||
<td>${esc(q.postinumero)}</td>
|
<td>${esc(q.postinumero)}</td>
|
||||||
<td>${esc(q.kaupunki)}</td>
|
<td>${esc(q.kaupunki)}</td>
|
||||||
<td>${badge}</td>
|
<td>${badge}</td>
|
||||||
|
<td style="font-size:0.8rem;">${ipInfo}</td>
|
||||||
<td style="font-size:0.8rem;color:#888;">${esc(source)}</td>
|
<td style="font-size:0.8rem;color:#888;">${esc(source)}</td>
|
||||||
<td style="font-size:0.8rem;color:#888;">${esc(q.company_nimi || q.company_id || '')}</td>
|
<td style="font-size:0.8rem;color:#888;">${esc(q.company_nimi || q.company_id || '')}</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
|
|||||||
Reference in New Issue
Block a user