Add multi-tenant support with per-company data isolation
Implement full multi-company architecture:
- Per-company directory structure (data/companies/{id}/)
- Automatic migration from single-tenant to multi-tenant
- Company management admin tab (create, edit, delete companies)
- Per-company IMAP mailbox configuration (multiple mailboxes per company)
- User access control per company (companies array on users)
- Company switcher in header (shown when user has access to >1 company)
- Session-based company context with check_auth fallback for old sessions
- Ticket list shows mailbox name instead of sender
- IMAP settings moved from global config to company-specific config
- All data endpoints protected with requireCompany() guard
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
143
index.html
143
index.html
@@ -61,6 +61,7 @@
|
||||
<span class="subtitle">Kuituasiakkaiden hallinta</span>
|
||||
</div>
|
||||
</div>
|
||||
<select id="company-selector" class="company-selector" style="display:none;"></select>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<span id="user-info" class="user-info"></span>
|
||||
@@ -77,6 +78,7 @@
|
||||
<button class="tab" data-tab="leads">Liidit</button>
|
||||
<button class="tab" data-tab="archive">Arkisto</button>
|
||||
<button class="tab" data-tab="changelog">Muutosloki</button>
|
||||
<button class="tab" data-tab="companies" id="tab-companies" style="display:none">Yritykset</button>
|
||||
<button class="tab" data-tab="settings" id="tab-settings" style="display:none">API</button>
|
||||
</div>
|
||||
|
||||
@@ -291,7 +293,7 @@
|
||||
<th>Tila</th>
|
||||
<th>Tyyppi</th>
|
||||
<th>Aihe</th>
|
||||
<th>Lähettäjä</th>
|
||||
<th>Postilaatikko</th>
|
||||
<th>Asiakas</th>
|
||||
<th>Tagit</th>
|
||||
<th>Viestejä</th>
|
||||
@@ -449,34 +451,7 @@
|
||||
<button class="btn-primary" id="btn-save-settings">Tallenna asetukset</button>
|
||||
</div>
|
||||
</div>
|
||||
<h3 style="color:#0f3460;margin:1.5rem 0 1rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">Sähköposti (IMAP)</h3>
|
||||
<p style="color:#666;font-size:0.85rem;margin-bottom:1rem;">Asiakaspalvelu-sähköpostin IMAP-asetukset. Käytetään tikettien hakuun.</p>
|
||||
<div class="form-grid" style="max-width:600px;">
|
||||
<div class="form-group">
|
||||
<label>IMAP-palvelin</label>
|
||||
<input type="text" id="settings-imap-host" placeholder="mail.example.com">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Portti</label>
|
||||
<input type="number" id="settings-imap-port" value="993" placeholder="993">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Käyttäjätunnus</label>
|
||||
<input type="text" id="settings-imap-user" placeholder="asiakaspalvelu@cuitunet.fi">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Salasana</label>
|
||||
<input type="password" id="settings-imap-password" placeholder="••••••••">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Salaus</label>
|
||||
<select id="settings-imap-encryption">
|
||||
<option value="ssl">SSL</option>
|
||||
<option value="tls">TLS</option>
|
||||
<option value="notls">Ei salausta</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<p style="color:#888;font-size:0.85rem;margin-top:1rem;">Sähköpostiasetukset (IMAP/postilaatikot) hallitaan Yritykset-välilehdellä.</p>
|
||||
<h3 style="color:#0f3460;margin:1.5rem 0 1rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">API-ohjeet</h3>
|
||||
<div style="background:#f8f9fb;padding:1rem;border-radius:8px;font-size:0.85rem;font-family:monospace;overflow-x:auto;">
|
||||
<div style="margin-bottom:0.75rem;"><strong>Endpoint:</strong><br>GET https://intra.cuitunet.fi/api.php?action=saatavuus</div>
|
||||
@@ -505,6 +480,112 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab: Yritykset (vain admin) -->
|
||||
<div class="tab-content" id="tab-content-companies">
|
||||
<div class="main-container">
|
||||
<!-- Yrityslistanäkymä -->
|
||||
<div id="companies-list-view">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;">
|
||||
<h3 style="color:#0f3460;margin:0;">Yritykset</h3>
|
||||
<button class="btn-primary" id="btn-add-company">+ Lisää yritys</button>
|
||||
</div>
|
||||
<div class="table-card">
|
||||
<table id="companies-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nimi</th>
|
||||
<th>Postilaatikot</th>
|
||||
<th>Luotu</th>
|
||||
<th>Tila</th>
|
||||
<th>Toiminnot</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="companies-tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Yrityksen asetukset -->
|
||||
<div id="company-detail-view" style="display:none;">
|
||||
<button class="btn-secondary" id="btn-company-back" style="color:#555;border-color:#ddd;margin-bottom:1rem;">← Takaisin yrityslistaan</button>
|
||||
<div class="table-card" style="padding:1.5rem;">
|
||||
<h3 style="color:#0f3460;margin-bottom:0.5rem;" id="company-detail-title">Yrityksen asetukset</h3>
|
||||
<div class="form-grid" style="max-width:400px;margin-bottom:1.5rem;">
|
||||
<div class="form-group">
|
||||
<label>Yrityksen nimi</label>
|
||||
<input type="text" id="company-edit-nimi">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn-primary" id="btn-save-company-name" style="font-size:0.85rem;">Tallenna nimi</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Postilaatikot -->
|
||||
<div class="table-card" style="padding:1.5rem;margin-top:1rem;">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;">
|
||||
<h3 style="color:#0f3460;margin:0;">Postilaatikot (IMAP)</h3>
|
||||
<button class="btn-primary" id="btn-add-mailbox" style="font-size:0.85rem;">+ Lisää postilaatikko</button>
|
||||
</div>
|
||||
<p style="color:#888;font-size:0.85rem;margin-bottom:1rem;">Sähköpostilaatikot joista asiakaspalvelutiketit haetaan.</p>
|
||||
<div id="mailboxes-list"></div>
|
||||
<!-- Postilaatikkolom -->
|
||||
<div id="mailbox-form-container" style="display:none;margin-top:1rem;padding:1rem;background:#f8f9fb;border-radius:8px;">
|
||||
<h4 style="color:#0f3460;margin-bottom:0.75rem;" id="mailbox-form-title">Uusi postilaatikko</h4>
|
||||
<input type="hidden" id="mailbox-form-id">
|
||||
<div class="form-grid" style="max-width:600px;">
|
||||
<div class="form-group full-width">
|
||||
<label>Nimi (näkyy tikettilistassa) *</label>
|
||||
<input type="text" id="mailbox-form-nimi" placeholder="esim. Cuitunet-asiakaspalvelu">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>IMAP-palvelin</label>
|
||||
<input type="text" id="mailbox-form-host" placeholder="mail.example.com">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Portti</label>
|
||||
<input type="number" id="mailbox-form-port" value="993" placeholder="993">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Käyttäjätunnus</label>
|
||||
<input type="text" id="mailbox-form-user" placeholder="asiakaspalvelu@cuitunet.fi">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Salasana</label>
|
||||
<input type="password" id="mailbox-form-password" placeholder="••••••••">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Salaus</label>
|
||||
<select id="mailbox-form-encryption">
|
||||
<option value="ssl">SSL</option>
|
||||
<option value="tls">TLS</option>
|
||||
<option value="notls">Ei salausta</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Lähettäjän sähköposti</label>
|
||||
<input type="text" id="mailbox-form-smtp-email" placeholder="asiakaspalvelu@cuitunet.fi">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Lähettäjän nimi</label>
|
||||
<input type="text" id="mailbox-form-smtp-name" placeholder="CuituNet Asiakaspalvelu">
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:0.5rem;margin-top:0.75rem;">
|
||||
<button class="btn-primary" id="btn-save-mailbox">Tallenna</button>
|
||||
<button class="btn-secondary" id="btn-cancel-mailbox">Peruuta</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Käyttäjäoikeudet -->
|
||||
<div class="table-card" style="padding:1.5rem;margin-top:1rem;">
|
||||
<h3 style="color:#0f3460;margin-bottom:0.5rem;">Käyttäjäoikeudet</h3>
|
||||
<p style="color:#888;font-size:0.85rem;margin-bottom:1rem;">Käyttäjät joilla on pääsy tähän yritykseen.</p>
|
||||
<div id="company-users-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>CuituNet Intra — Asiakashallintajärjestelmä</p>
|
||||
</footer>
|
||||
@@ -645,6 +726,10 @@
|
||||
<option value="admin">Ylläpitäjä</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group full-width">
|
||||
<label>Yritysoikeudet</label>
|
||||
<div id="user-company-checkboxes" style="display:flex;flex-wrap:wrap;gap:0.75rem;margin-top:0.25rem;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn-primary">Tallenna</button>
|
||||
|
||||
Reference in New Issue
Block a user