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 <noreply@anthropic.com>
This commit is contained in:
93
api.php
93
api.php
@@ -890,9 +890,35 @@ switch ($action) {
|
|||||||
|
|
||||||
// ---------- SAATAVUUS (julkinen API) ----------
|
// ---------- SAATAVUUS (julkinen API) ----------
|
||||||
case 'saatavuus':
|
case 'saatavuus':
|
||||||
// CORS - salli cuitunet.fi
|
$providedKey = $_GET['key'] ?? ($_SERVER['HTTP_X_API_KEY'] ?? '');
|
||||||
$config = loadConfig();
|
if (empty($providedKey)) {
|
||||||
$allowedOrigins = $config['cors_origins'] ?? ['https://cuitunet.fi', 'https://www.cuitunet.fi'];
|
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'] ?? '';
|
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
|
||||||
if (in_array($origin, $allowedOrigins)) {
|
if (in_array($origin, $allowedOrigins)) {
|
||||||
header("Access-Control-Allow-Origin: $origin");
|
header("Access-Control-Allow-Origin: $origin");
|
||||||
@@ -901,16 +927,7 @@ switch ($action) {
|
|||||||
}
|
}
|
||||||
if ($method === 'OPTIONS') { http_response_code(204); break; }
|
if ($method === 'OPTIONS') { http_response_code(204); break; }
|
||||||
|
|
||||||
// API-avain tarkistus
|
// Parametrit
|
||||||
$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
|
|
||||||
$queryOsoite = normalizeAddress($_GET['osoite'] ?? '');
|
$queryOsoite = normalizeAddress($_GET['osoite'] ?? '');
|
||||||
$queryPostinumero = trim($_GET['postinumero'] ?? '');
|
$queryPostinumero = trim($_GET['postinumero'] ?? '');
|
||||||
$queryKaupunki = strtolower(trim($_GET['kaupunki'] ?? ''));
|
$queryKaupunki = strtolower(trim($_GET['kaupunki'] ?? ''));
|
||||||
@@ -921,13 +938,11 @@ switch ($action) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hae kaikista yrityksistä
|
// Hae VAIN tämän yrityksen asiakkaista
|
||||||
$allCompanies = loadCompanies();
|
$compDir = DATA_DIR . '/companies/' . $matchedCompany['id'];
|
||||||
$found = false;
|
|
||||||
foreach ($allCompanies as $comp) {
|
|
||||||
$compDir = DATA_DIR . '/companies/' . $comp['id'];
|
|
||||||
$custFile = $compDir . '/customers.json';
|
$custFile = $compDir . '/customers.json';
|
||||||
if (!file_exists($custFile)) continue;
|
$found = false;
|
||||||
|
if (file_exists($custFile)) {
|
||||||
$customers = json_decode(file_get_contents($custFile), true) ?: [];
|
$customers = json_decode(file_get_contents($custFile), true) ?: [];
|
||||||
foreach ($customers as $c) {
|
foreach ($customers as $c) {
|
||||||
foreach ($c['liittymat'] ?? [] as $l) {
|
foreach ($c['liittymat'] ?? [] as $l) {
|
||||||
@@ -938,7 +953,7 @@ switch ($action) {
|
|||||||
if (!empty($addr) && !empty($queryOsoite)) {
|
if (!empty($addr) && !empty($queryOsoite)) {
|
||||||
if (strpos($addr, $queryOsoite) !== false || strpos($queryOsoite, $addr) !== false) {
|
if (strpos($addr, $queryOsoite) !== false || strpos($queryOsoite, $addr) !== false) {
|
||||||
$found = true;
|
$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]);
|
echo json_encode(['saatavilla' => $found]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ---------- CONFIG (admin) ----------
|
// ---------- CONFIG (admin, yrityskohtainen) ----------
|
||||||
case 'config':
|
case 'config':
|
||||||
requireAdmin();
|
requireAdmin();
|
||||||
echo json_encode(loadConfig());
|
requireCompany();
|
||||||
|
$compConf = loadCompanyConfig();
|
||||||
|
echo json_encode([
|
||||||
|
'api_key' => $compConf['api_key'] ?? '',
|
||||||
|
'cors_origins' => $compConf['cors_origins'] ?? [],
|
||||||
|
]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'config_update':
|
case 'config_update':
|
||||||
requireAdmin();
|
requireAdmin();
|
||||||
|
requireCompany();
|
||||||
if ($method !== 'POST') break;
|
if ($method !== 'POST') break;
|
||||||
$input = json_decode(file_get_contents('php://input'), true);
|
$input = json_decode(file_get_contents('php://input'), true);
|
||||||
$config = loadConfig();
|
$compConf = loadCompanyConfig();
|
||||||
if (isset($input['api_key'])) $config['api_key'] = trim($input['api_key']);
|
if (isset($input['api_key'])) $compConf['api_key'] = trim($input['api_key']);
|
||||||
if (isset($input['cors_origins'])) {
|
if (isset($input['cors_origins'])) {
|
||||||
$origins = array_filter(array_map('trim', explode("\n", $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);
|
saveCompanyConfig($compConf);
|
||||||
addLog('config_update', '', '', 'Päivitti asetukset');
|
addLog('config_update', '', '', 'Päivitti API-asetukset');
|
||||||
echo json_encode($config);
|
echo json_encode([
|
||||||
|
'api_key' => $compConf['api_key'] ?? '',
|
||||||
|
'cors_origins' => $compConf['cors_origins'] ?? [],
|
||||||
|
]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'generate_api_key':
|
case 'generate_api_key':
|
||||||
requireAdmin();
|
requireAdmin();
|
||||||
|
requireCompany();
|
||||||
if ($method !== 'POST') break;
|
if ($method !== 'POST') break;
|
||||||
$config = loadConfig();
|
$compConf = loadCompanyConfig();
|
||||||
$config['api_key'] = bin2hex(random_bytes(16));
|
$compConf['api_key'] = bin2hex(random_bytes(16));
|
||||||
saveConfig($config);
|
saveCompanyConfig($compConf);
|
||||||
addLog('config_update', '', '', 'Generoi uuden API-avaimen');
|
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;
|
break;
|
||||||
|
|
||||||
// ---------- CAPTCHA ----------
|
// ---------- CAPTCHA ----------
|
||||||
|
|||||||
@@ -437,7 +437,7 @@
|
|||||||
<div class="tab-content" id="tab-content-settings">
|
<div class="tab-content" id="tab-content-settings">
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<div class="table-card" style="padding:1.5rem;">
|
<div class="table-card" style="padding:1.5rem;">
|
||||||
<h3 style="color:#0f3460;margin-bottom:1rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">Saatavuus-API</h3>
|
<h3 style="color:#0f3460;margin-bottom:1rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;"><span id="api-company-name"></span>Saatavuus-API</h3>
|
||||||
<p style="color:#666;font-size:0.85rem;margin-bottom:1rem;">Julkinen API jolla cuitunet.fi voi tarkistaa kuituverkon saatavuuden osoitteessa. Palauttaa vain osoite + nopeus - ei asiakastietoja.</p>
|
<p style="color:#666;font-size:0.85rem;margin-bottom:1rem;">Julkinen API jolla cuitunet.fi voi tarkistaa kuituverkon saatavuuden osoitteessa. Palauttaa vain osoite + nopeus - ei asiakastietoja.</p>
|
||||||
<div class="form-grid" style="max-width:600px;">
|
<div class="form-grid" style="max-width:600px;">
|
||||||
<div class="form-group full-width">
|
<div class="form-group full-width">
|
||||||
|
|||||||
@@ -1643,7 +1643,10 @@ async function loadSettings() {
|
|||||||
try {
|
try {
|
||||||
const config = await apiCall('config');
|
const config = await apiCall('config');
|
||||||
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 || []).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';
|
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`;
|
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); }
|
||||||
|
|||||||
Reference in New Issue
Block a user