From 44e401f4d30c278c1979a27f5de4c695b69bcf66 Mon Sep 17 00:00:00 2001 From: Jukka Lampikoski Date: Tue, 10 Mar 2026 11:39:35 +0200 Subject: [PATCH] Make API key and CORS settings per-company - saatavuus endpoint finds company by API key, searches only that company - config/config_update/generate_api_key now use company config - API tab shows active company name - Each company has own api_key and cors_origins in their config.json Co-Authored-By: Claude Opus 4.6 --- api.php | 93 +++++++++++++++++++++++++++++++++++------------------- index.html | 2 +- script.js | 5 ++- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/api.php b/api.php index c2981f4..2c531be 100644 --- a/api.php +++ b/api.php @@ -890,9 +890,35 @@ switch ($action) { // ---------- SAATAVUUS (julkinen API) ---------- case 'saatavuus': - // CORS - salli cuitunet.fi - $config = loadConfig(); - $allowedOrigins = $config['cors_origins'] ?? ['https://cuitunet.fi', 'https://www.cuitunet.fi']; + $providedKey = $_GET['key'] ?? ($_SERVER['HTTP_X_API_KEY'] ?? ''); + if (empty($providedKey)) { + http_response_code(403); + echo json_encode(['error' => 'API-avain puuttuu']); + break; + } + + // Etsi yritys jonka API-avain täsmää + $matchedCompany = null; + $allCompanies = loadCompanies(); + foreach ($allCompanies as $comp) { + $confFile = DATA_DIR . '/companies/' . $comp['id'] . '/config.json'; + if (!file_exists($confFile)) continue; + $compConf = json_decode(file_get_contents($confFile), true) ?: []; + if (!empty($compConf['api_key']) && $compConf['api_key'] === $providedKey) { + $matchedCompany = $comp; + $matchedConfig = $compConf; + break; + } + } + + if (!$matchedCompany) { + http_response_code(403); + echo json_encode(['error' => 'Virheellinen API-avain']); + break; + } + + // CORS - yrityskohtaiset originit + $allowedOrigins = $matchedConfig['cors_origins'] ?? []; $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; if (in_array($origin, $allowedOrigins)) { header("Access-Control-Allow-Origin: $origin"); @@ -901,16 +927,7 @@ switch ($action) { } if ($method === 'OPTIONS') { http_response_code(204); break; } - // API-avain tarkistus - $apiKey = $config['api_key'] ?? ''; - $providedKey = $_GET['key'] ?? ($_SERVER['HTTP_X_API_KEY'] ?? ''); - if (empty($apiKey) || $providedKey !== $apiKey) { - http_response_code(403); - echo json_encode(['error' => 'Virheellinen API-avain']); - break; - } - - // Parametrit: osoite (kadunnimi + numero), postinumero, kaupunki + // Parametrit $queryOsoite = normalizeAddress($_GET['osoite'] ?? ''); $queryPostinumero = trim($_GET['postinumero'] ?? ''); $queryKaupunki = strtolower(trim($_GET['kaupunki'] ?? '')); @@ -921,13 +938,11 @@ switch ($action) { break; } - // Hae kaikista yrityksistä - $allCompanies = loadCompanies(); + // Hae VAIN tämän yrityksen asiakkaista + $compDir = DATA_DIR . '/companies/' . $matchedCompany['id']; + $custFile = $compDir . '/customers.json'; $found = false; - foreach ($allCompanies as $comp) { - $compDir = DATA_DIR . '/companies/' . $comp['id']; - $custFile = $compDir . '/customers.json'; - if (!file_exists($custFile)) continue; + if (file_exists($custFile)) { $customers = json_decode(file_get_contents($custFile), true) ?: []; foreach ($customers as $c) { foreach ($c['liittymat'] ?? [] as $l) { @@ -938,7 +953,7 @@ switch ($action) { if (!empty($addr) && !empty($queryOsoite)) { if (strpos($addr, $queryOsoite) !== false || strpos($queryOsoite, $addr) !== false) { $found = true; - break 3; + break 2; } } } @@ -946,39 +961,51 @@ switch ($action) { } } - // Palauta VAIN true/false - ei osoitteita, nopeuksia tai muuta dataa echo json_encode(['saatavilla' => $found]); break; - // ---------- CONFIG (admin) ---------- + // ---------- CONFIG (admin, yrityskohtainen) ---------- case 'config': requireAdmin(); - echo json_encode(loadConfig()); + requireCompany(); + $compConf = loadCompanyConfig(); + echo json_encode([ + 'api_key' => $compConf['api_key'] ?? '', + 'cors_origins' => $compConf['cors_origins'] ?? [], + ]); break; case 'config_update': requireAdmin(); + requireCompany(); if ($method !== 'POST') break; $input = json_decode(file_get_contents('php://input'), true); - $config = loadConfig(); - if (isset($input['api_key'])) $config['api_key'] = trim($input['api_key']); + $compConf = loadCompanyConfig(); + if (isset($input['api_key'])) $compConf['api_key'] = trim($input['api_key']); if (isset($input['cors_origins'])) { $origins = array_filter(array_map('trim', explode("\n", $input['cors_origins']))); - $config['cors_origins'] = array_values($origins); + $compConf['cors_origins'] = array_values($origins); } - saveConfig($config); - addLog('config_update', '', '', 'Päivitti asetukset'); - echo json_encode($config); + saveCompanyConfig($compConf); + addLog('config_update', '', '', 'Päivitti API-asetukset'); + echo json_encode([ + 'api_key' => $compConf['api_key'] ?? '', + 'cors_origins' => $compConf['cors_origins'] ?? [], + ]); break; case 'generate_api_key': requireAdmin(); + requireCompany(); if ($method !== 'POST') break; - $config = loadConfig(); - $config['api_key'] = bin2hex(random_bytes(16)); - saveConfig($config); + $compConf = loadCompanyConfig(); + $compConf['api_key'] = bin2hex(random_bytes(16)); + saveCompanyConfig($compConf); addLog('config_update', '', '', 'Generoi uuden API-avaimen'); - echo json_encode($config); + echo json_encode([ + 'api_key' => $compConf['api_key'] ?? '', + 'cors_origins' => $compConf['cors_origins'] ?? [], + ]); break; // ---------- CAPTCHA ---------- diff --git a/index.html b/index.html index 22dbf54..09f72d1 100644 --- a/index.html +++ b/index.html @@ -437,7 +437,7 @@
-

Saatavuus-API

+

Saatavuus-API

Julkinen API jolla cuitunet.fi voi tarkistaa kuituverkon saatavuuden osoitteessa. Palauttaa vain osoite + nopeus - ei asiakastietoja.

diff --git a/script.js b/script.js index ea2092f..d85f443 100644 --- a/script.js +++ b/script.js @@ -1643,7 +1643,10 @@ async function loadSettings() { try { const config = await apiCall('config'); 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 || []).join('\n'); + // Näytä yrityksen nimi API-otsikossa + const apiTitle = document.getElementById('api-company-name'); + if (apiTitle && currentCompany) apiTitle.textContent = currentCompany.nimi + ' — '; const key = config.api_key || 'AVAIN'; document.getElementById('api-example-url').textContent = `api.php?action=saatavuus&key=${key}&osoite=Kauppakatu+5&postinumero=20100&kaupunki=Turku`; } catch (e) { console.error(e); }