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:
2026-03-10 11:39:35 +02:00
parent 92d52f34ad
commit 44e401f4d3
3 changed files with 65 additions and 35 deletions

93
api.php
View File

@@ -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 ----------