Restrict saatavuus API to return only true/false
Requires exact match of osoite + postinumero + kaupunki. No longer exposes addresses, speeds, or any customer data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
api.php
64
api.php
@@ -287,70 +287,40 @@ switch ($action) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$query = normalizeAddress($_GET['osoite'] ?? '');
|
// Parametrit: osoite (kadunnimi + numero), postinumero, kaupunki
|
||||||
$postinumero = trim($_GET['postinumero'] ?? '');
|
$queryOsoite = normalizeAddress($_GET['osoite'] ?? '');
|
||||||
|
$queryPostinumero = trim($_GET['postinumero'] ?? '');
|
||||||
|
$queryKaupunki = strtolower(trim($_GET['kaupunki'] ?? ''));
|
||||||
|
|
||||||
if (empty($query) && empty($postinumero)) {
|
if (empty($queryOsoite) || empty($queryPostinumero) || empty($queryKaupunki)) {
|
||||||
http_response_code(400);
|
http_response_code(400);
|
||||||
echo json_encode(['error' => 'Anna osoite tai postinumero']);
|
echo json_encode(['error' => 'Anna osoite, postinumero ja kaupunki']);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$customers = loadCustomers();
|
$customers = loadCustomers();
|
||||||
$matches = [];
|
$found = false;
|
||||||
foreach ($customers as $c) {
|
foreach ($customers as $c) {
|
||||||
foreach ($c['liittymat'] ?? [] as $l) {
|
foreach ($c['liittymat'] ?? [] as $l) {
|
||||||
$addr = normalizeAddress($l['asennusosoite'] ?? '');
|
$addr = normalizeAddress($l['asennusosoite'] ?? '');
|
||||||
$zip = trim($l['postinumero'] ?? '');
|
$zip = trim($l['postinumero'] ?? '');
|
||||||
$city = strtolower(trim($l['kaupunki'] ?? ''));
|
$city = strtolower(trim($l['kaupunki'] ?? ''));
|
||||||
$hit = false;
|
|
||||||
|
|
||||||
// Postinumero-haku
|
// Kaikki kolme pitää mätsätä: osoite, postinumero, kaupunki
|
||||||
if (!empty($postinumero) && $zip === $postinumero) {
|
if ($zip === $queryPostinumero && $city === $queryKaupunki) {
|
||||||
$hit = true;
|
// Osoite-match: tarkka sisältö-match
|
||||||
}
|
if (!empty($addr) && !empty($queryOsoite)) {
|
||||||
|
if (strpos($addr, $queryOsoite) !== false || strpos($queryOsoite, $addr) !== false) {
|
||||||
// Osoitehaku (sisältää haun)
|
$found = true;
|
||||||
if (!empty($query) && !empty($addr)) {
|
break 2;
|
||||||
if (strpos($addr, $query) !== false || strpos($query, $addr) !== false) {
|
}
|
||||||
$hit = true;
|
|
||||||
}
|
}
|
||||||
// Kadunnimi-match (ilman numeroa)
|
|
||||||
$queryStreet = trim(preg_replace('/\d+.*$/', '', $query));
|
|
||||||
$addrStreet = trim(preg_replace('/\d+.*$/', '', $addr));
|
|
||||||
if (!empty($queryStreet) && !empty($addrStreet) && strpos($addrStreet, $queryStreet) !== false) {
|
|
||||||
$hit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($hit) {
|
|
||||||
// Palauta VAIN osoitetieto ja nopeus - ei asiakastietoja
|
|
||||||
$matches[] = [
|
|
||||||
'osoite' => $l['asennusosoite'] ?? '',
|
|
||||||
'postinumero' => $zip,
|
|
||||||
'kaupunki' => $l['kaupunki'] ?? '',
|
|
||||||
'nopeus' => $l['liittymanopeus'] ?? '',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poista duplikaatit (sama osoite eri asiakkailla)
|
// Palauta VAIN true/false - ei osoitteita, nopeuksia tai muuta dataa
|
||||||
$unique = [];
|
echo json_encode(['saatavilla' => $found]);
|
||||||
$seen = [];
|
|
||||||
foreach ($matches as $m) {
|
|
||||||
$key = normalizeAddress($m['osoite'] . $m['postinumero']);
|
|
||||||
if (!isset($seen[$key])) {
|
|
||||||
$unique[] = $m;
|
|
||||||
$seen[$key] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode([
|
|
||||||
'saatavilla' => count($unique) > 0,
|
|
||||||
'kohteet' => $unique,
|
|
||||||
'maara' => count($unique),
|
|
||||||
]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ---------- CONFIG (admin) ----------
|
// ---------- CONFIG (admin) ----------
|
||||||
|
|||||||
17
index.html
17
index.html
@@ -286,17 +286,22 @@
|
|||||||
<div style="margin-bottom:0.75rem;"><strong>Endpoint:</strong><br>GET https://intra.cuitunet.fi/api.php?action=saatavuus</div>
|
<div style="margin-bottom:0.75rem;"><strong>Endpoint:</strong><br>GET https://intra.cuitunet.fi/api.php?action=saatavuus</div>
|
||||||
<div style="margin-bottom:0.75rem;"><strong>Parametrit:</strong><br>
|
<div style="margin-bottom:0.75rem;"><strong>Parametrit:</strong><br>
|
||||||
• <code>key</code> = API-avain (pakollinen)<br>
|
• <code>key</code> = API-avain (pakollinen)<br>
|
||||||
• <code>osoite</code> = Haettava osoite (esim. "Kauppakatu 5")<br>
|
• <code>osoite</code> = Katuosoite ja numero (esim. "Kauppakatu 5")<br>
|
||||||
• <code>postinumero</code> = Postinumero (esim. "20100")<br>
|
• <code>postinumero</code> = Postinumero (esim. "20100")<br>
|
||||||
Anna vähintään toinen: osoite tai postinumero.</div>
|
• <code>kaupunki</code> = Kaupunki (esim. "Turku")<br>
|
||||||
|
Kaikki kolme pakollisia.</div>
|
||||||
<div style="margin-bottom:0.75rem;"><strong>Esimerkki:</strong><br>
|
<div style="margin-bottom:0.75rem;"><strong>Esimerkki:</strong><br>
|
||||||
<code id="api-example-url">api.php?action=saatavuus&key=AVAIN&osoite=Kauppakatu+5</code></div>
|
<code id="api-example-url">api.php?action=saatavuus&key=AVAIN&osoite=Kauppakatu+5&postinumero=20100&kaupunki=Turku</code></div>
|
||||||
<div><strong>Vastaus:</strong><br>
|
<div><strong>Vastaus:</strong><br>
|
||||||
<code>{"saatavilla":true,"kohteet":[{"osoite":"...","postinumero":"...","kaupunki":"...","nopeus":"..."}],"maara":1}</code></div>
|
<code>{"saatavilla":true}</code> tai <code>{"saatavilla":false}</code></div>
|
||||||
</div>
|
</div>
|
||||||
<h3 style="color:#0f3460;margin:1.5rem 0 1rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">Testaa API</h3>
|
<h3 style="color:#0f3460;margin:1.5rem 0 1rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">Testaa API</h3>
|
||||||
<div style="display:flex;gap:0.5rem;max-width:500px;">
|
<div style="display:grid;grid-template-columns:1fr;gap:0.5rem;max-width:500px;">
|
||||||
<input type="text" id="test-api-address" placeholder="Osoite tai postinumero" style="flex:1;">
|
<input type="text" id="test-api-address" placeholder="Osoite (esim. Kauppakatu 5)">
|
||||||
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;">
|
||||||
|
<input type="text" id="test-api-zip" placeholder="Postinumero" maxlength="5">
|
||||||
|
<input type="text" id="test-api-city" placeholder="Kaupunki">
|
||||||
|
</div>
|
||||||
<button class="btn-primary" id="btn-test-api">Testaa</button>
|
<button class="btn-primary" id="btn-test-api">Testaa</button>
|
||||||
</div>
|
</div>
|
||||||
<pre id="test-api-result" style="margin-top:0.75rem;background:#f8f9fb;padding:1rem;border-radius:8px;font-size:0.85rem;display:none;overflow-x:auto;"></pre>
|
<pre id="test-api-result" style="margin-top:0.75rem;background:#f8f9fb;padding:1rem;border-radius:8px;font-size:0.85rem;display:none;overflow-x:auto;"></pre>
|
||||||
|
|||||||
15
script.js
15
script.js
@@ -928,7 +928,7 @@ async function loadSettings() {
|
|||||||
document.getElementById('settings-api-key').value = config.api_key || '';
|
document.getElementById('settings-api-key').value = config.api_key || '';
|
||||||
document.getElementById('settings-cors').value = (config.cors_origins || ['https://cuitunet.fi', 'https://www.cuitunet.fi']).join('\n');
|
document.getElementById('settings-cors').value = (config.cors_origins || ['https://cuitunet.fi', 'https://www.cuitunet.fi']).join('\n');
|
||||||
const key = config.api_key || 'AVAIN';
|
const key = config.api_key || 'AVAIN';
|
||||||
document.getElementById('api-example-url').textContent = `api.php?action=saatavuus&key=${key}&osoite=Kauppakatu+5`;
|
document.getElementById('api-example-url').textContent = `api.php?action=saatavuus&key=${key}&osoite=Kauppakatu+5&postinumero=20100&kaupunki=Turku`;
|
||||||
} catch (e) { console.error(e); }
|
} catch (e) { console.error(e); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,7 +936,7 @@ document.getElementById('btn-generate-key').addEventListener('click', async () =
|
|||||||
try {
|
try {
|
||||||
const config = await apiCall('generate_api_key', 'POST');
|
const config = await apiCall('generate_api_key', 'POST');
|
||||||
document.getElementById('settings-api-key').value = config.api_key || '';
|
document.getElementById('settings-api-key').value = config.api_key || '';
|
||||||
document.getElementById('api-example-url').textContent = `api.php?action=saatavuus&key=${config.api_key}&osoite=Kauppakatu+5`;
|
document.getElementById('api-example-url').textContent = `api.php?action=saatavuus&key=${config.api_key}&osoite=Kauppakatu+5&postinumero=20100&kaupunki=Turku`;
|
||||||
} catch (e) { alert(e.message); }
|
} catch (e) { alert(e.message); }
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -951,16 +951,17 @@ document.getElementById('btn-save-settings').addEventListener('click', async ()
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('btn-test-api').addEventListener('click', async () => {
|
document.getElementById('btn-test-api').addEventListener('click', async () => {
|
||||||
const address = document.getElementById('test-api-address').value.trim();
|
const osoite = document.getElementById('test-api-address').value.trim();
|
||||||
|
const postinumero = document.getElementById('test-api-zip').value.trim();
|
||||||
|
const kaupunki = document.getElementById('test-api-city').value.trim();
|
||||||
const apiKey = document.getElementById('settings-api-key').value;
|
const apiKey = document.getElementById('settings-api-key').value;
|
||||||
if (!address) { alert('Anna osoite tai postinumero'); return; }
|
if (!osoite || !postinumero || !kaupunki) { alert('Täytä osoite, postinumero ja kaupunki'); return; }
|
||||||
const result = document.getElementById('test-api-result');
|
const result = document.getElementById('test-api-result');
|
||||||
result.style.display = 'block';
|
result.style.display = 'block';
|
||||||
result.textContent = 'Haetaan...';
|
result.textContent = 'Haetaan...';
|
||||||
try {
|
try {
|
||||||
const isZip = /^\d{5}$/.test(address);
|
const params = `osoite=${encodeURIComponent(osoite)}&postinumero=${encodeURIComponent(postinumero)}&kaupunki=${encodeURIComponent(kaupunki)}`;
|
||||||
const param = isZip ? `postinumero=${encodeURIComponent(address)}` : `osoite=${encodeURIComponent(address)}`;
|
const res = await fetch(`${API}?action=saatavuus&key=${encodeURIComponent(apiKey)}&${params}`);
|
||||||
const res = await fetch(`${API}?action=saatavuus&key=${encodeURIComponent(apiKey)}&${param}`);
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
result.textContent = JSON.stringify(data, null, 2);
|
result.textContent = JSON.stringify(data, null, 2);
|
||||||
} catch (e) { result.textContent = 'Virhe: ' + e.message; }
|
} catch (e) { result.textContent = 'Virhe: ' + e.message; }
|
||||||
|
|||||||
Reference in New Issue
Block a user