Superadmin-rajoitus: moduulit, integraatiot ja IP-asetukset vain pääkäyttäjälle + captcha-sessiokorjaus

- Moduulit, integraatiot ja IP-rajoitukset piilotetaan yritysadminilta (vain superadmin näkee)
- Saatavuus-API ja Telegram checkboxit tallentavat tilan heti muutoksessa
- session_regenerate_id(false) estää race conditionin kirjautumisen jälkeen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 19:49:57 +02:00
parent 1ab669a490
commit 648cb949ac
3 changed files with 20 additions and 8 deletions

View File

@@ -1460,7 +1460,8 @@ switch ($action) {
}
}
session_regenerate_id(true);
// false = säilytä vanha sessio hetken (estää race condition kun frontend lataa heti dataa)
session_regenerate_id(false);
$_SESSION['user_id'] = $u['id'];
$_SESSION['username'] = $u['username'];
$_SESSION['nimi'] = $u['nimi'];

View File

@@ -1597,8 +1597,8 @@
<textarea id="company-edit-domains" rows="3" placeholder="intra.yritys.fi&#10;intra.toinen.fi" style="font-family:monospace;font-size:0.85rem;"></textarea>
</div>
</div>
<!-- Moduulit -->
<div style="margin-bottom:1.5rem;">
<!-- Moduulit (vain superadmin) -->
<div id="company-modules-section" style="margin-bottom:1.5rem;display:none;">
<h4 style="color:#0f3460;margin-bottom:0.5rem;font-size:0.95rem;">Käytössä olevat moduulit</h4>
<p style="color:#888;font-size:0.82rem;margin-bottom:0.75rem;">Valitse mitkä välilehdet ovat käytössä tässä yrityksessä.</p>
<div id="modules-checkboxes" style="display:flex;flex-direction:column;gap:0.4rem;">
@@ -1640,8 +1640,8 @@
</label>
</div>
</div>
<!-- Integraatiot -->
<div style="margin-bottom:1.5rem;">
<!-- Integraatiot (vain superadmin) -->
<div id="company-integrations-section" style="margin-bottom:1.5rem;display:none;">
<h4 style="color:#0f3460;margin-bottom:0.5rem;font-size:0.95rem;">Integraatiot</h4>
<p style="color:#888;font-size:0.82rem;margin-bottom:0.75rem;">Ota käyttöön ulkoiset integraatiot tälle yritykselle.</p>
<div id="integrations-checkboxes" style="display:flex;flex-direction:column;gap:0.4rem;">
@@ -1680,7 +1680,7 @@
</div>
<div id="company-zammad-result" style="margin-top:0.75rem;display:none;padding:0.75rem;border-radius:8px;font-size:0.85rem;"></div>
</div>
<div class="form-group" style="margin-top:1rem;">
<div id="company-allowed-ips-section" class="form-group" style="margin-top:1rem;display:none;">
<label style="font-weight:600;font-size:0.9rem;">Sallitut IP-osoitteet</label>
<textarea id="company-edit-allowed-ips" rows="3" style="font-family:monospace;font-size:0.85rem;" placeholder="192.168.1.100&#10;10.0.0.0/8"></textarea>
<small style="color:#888;">Yksi IP tai CIDR per rivi. "kaikki" = ei rajoitusta.</small>

View File

@@ -2568,6 +2568,17 @@ async function showCompanyDetail(id) {
logoPreview.style.display = 'none';
}
// Superadmin-osiot: moduulit, integraatiot, IP-rajoitukset
const isSA = currentUser?.role === 'superadmin';
const modulesSection = document.getElementById('company-modules-section');
const integrationsSection = document.getElementById('company-integrations-section');
const zammadConfig = document.getElementById('company-zammad-config');
const ipsSection = document.getElementById('company-allowed-ips-section');
if (modulesSection) modulesSection.style.display = isSA ? '' : 'none';
if (integrationsSection) integrationsSection.style.display = isSA ? '' : 'none';
if (!isSA && zammadConfig) zammadConfig.style.display = 'none';
if (ipsSection) ipsSection.style.display = isSA ? '' : 'none';
// Moduuli-checkboxit (yhteensopivuus: vanha 'devices' → 'tekniikka')
let enabledMods = comp?.enabled_modules || [];
if (enabledMods.includes('devices') && !enabledMods.includes('tekniikka')) {
@@ -2585,8 +2596,8 @@ async function showCompanyDetail(id) {
// Vaihda aktiivinen yritys jotta API-kutsut kohdistuvat oikein
await apiCall('company_switch', 'POST', { company_id: id });
// Integraatiot — lataa tila
loadCompanyIntegrations();
// Integraatiot — lataa tila (vain superadmin)
if (isSA) loadCompanyIntegrations();
// Lataa postilaatikot
loadMailboxes();