- Poista SMTP override-testikentät (ei tarpeen enää)
- Tallennus pitää lomakkeen auki + näyttää "Tallennettu" -ilmoituksen
- SMTP-kenttäjärjestys samaksi kuin IMAP: Palvelin → Portti → Tunnus → Salasana → Salaus
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Captcha: loadBranding() ensin, sitten captcha+auth, jotta sessio-cookie
on luotu ennen captcha-latausta (estää eri sessiot rinnakkaisilla kutsuilla).
SMTP-testi: lisää salasanavihje (3 ensimmäistä + 2 viimeistä merkkiä),
override-kentät joilla voi testata eri tunnuksilla suoraan ilman DB:tä.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Korvaa mailbox_debug-endpoint kattavalla smtp_test-endpointilla,
joka testaa yhteyden, TLS:n ja autentikoinnin vaihe vaiheelta.
"Testaa SMTP" -nappi lomakkeessa näyttää tulokset.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jos smtp_user on tyhjä, käytetään imap_useria, sitten
smtp_from_emailia. Jos smtp_password on tyhjä, käytetään
imap_passwordia. Korjaa tilanteen jossa imap_user-kenttä
on tyhjä mutta salasana ja asetukset ovat oikein.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Näyttää smtp_host, smtp_port, smtp_user, smtp_pass_len,
imap_host, imap_user, imap_pass_len suoraan alertissa
niin nähdään heti onko asetukset oikein.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Kun SMTP-salasana jää tyhjäksi (vanha SMTP-salasana ei ole
koskaan asetettu) mutta käyttäjätunnus on sama kuin IMAP:ssa,
kopioidaan automaattisesti IMAP-salasana SMTP:lle. Korjaa
AUTH-virheen joka tuli koska SMTP-salasana tallentui tyhjänä.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Virheviesti palautetaan nyt frontendille tarkan SMTP-vaiheen
kera (connect, STARTTLS, AUTH, MAIL FROM, RCPT TO, DATA, send),
jotta nähdään missä kohtaa lähetys epäonnistuu.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jos käyttäjä ei ole asettanut omaa allekirjoitusta mailboxille,
generoidaan automaattisesti oletus:
Etunimi
Yrityksen nimi
Postilaatikon sähköpostiosoite
Toimii sekä esikatselu-previewssä että sähköpostin lähetyksessä.
Käyttäjä voi yliajaa oletuksen tallentamalla oman allekirjoituksen
profiilin kautta.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Aiemmin sähköpostit lähetettiin PHP mail()-funktiolla, mikä
ei toimi kunnolla useimmilla palvelimilla (SPF/DKIM-ongelmat).
Nyt mailboxiin voi konfiguroida SMTP-asetukset (host, port,
user, pass, encryption), ja lähetys tapahtuu suoraan
SMTP-palvelimen kautta socket-yhteydellä. Fallback PHP
mail():iin jos SMTP-asetuksia ei ole asetettu.
- db.php: smtp_host/port/user/password/encryption sarakkeet
- api.php: sendViaSMTP() socket-pohjainen SMTP-client
- index.html: SMTP-kentät mailbox-lomakkeeseen
- script.js: SMTP-kenttien luku/kirjoitus lomakkeessa
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Vastaanottaja (TO) näkyy nyt Lähettäjä- ja CC-kenttien välissä
- Esitäytetään tiketin alkuperäisen lähettäjän osoitteella
- Muokattavissa ennen lähetystä
- Backend käyttää frontendistä tullutta TO:ta tai fallbackina from_email
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Lisätty "Oma profiili" -nappi headeriin (⚙ + nimen klikkaus)
- Profiili-modaali: muokkaa nimi, sähköposti, salasana, allekirjoitukset
- Uusi profile_update API-endpoint (vaatii vain kirjautumisen)
- check_auth palauttaa nyt myös email-kentän
- Siivottu kaikki yrityskohtaiset placeholder-tekstit geneerisiksi
(cuitunet.fi → yritys.fi, Kauppakatu → Esimerkkikatu, jne.)
- Poistettu väliaikaiset fix_role.php ja fix_saatavuus.php
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Käyttäjät-nappi näkyy nyt myös admin-roolille
- Admin näkee/hallitsee vain oman yrityksensä käyttäjiä
- Admin voi luoda admin/user-rooleja (ei superadmin)
- Admin ei voi poistaa/muokata superadmineja
- Superadmin-vaihtoehto piilotettu rooli-dropdownista adminilta
- Yritysoikeudet-osio piilotettu adminilta (lisätään automaattisesti)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Korvattu yleinen lisätiedot-tekstikenttä neljällä erillisellä
kentällä (vlan, laite, portti, ip) jotta tiedoista voi hakea
ja filtteröidä tarkemmin.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Moduulijärjestelmä: yrityskohtaiset tabit (customers, support, leads, archive,
changelog, settings) valittavissa checkboxeina yrityksen asetuksissa
- Käyttäjäroolit: superadmin (pääkäyttäjä), admin (yritysadmin), user (käyttäjä)
- Superadmin: kaikki oikeudet kuten ennen
- Yritysadmin: muokkaa oman yrityksen asetuksia, moduuleita, postilaatikoita
- Käyttäjä: peruskäyttö ilman hallintaoikeuksia
- Päivitetty-kenttä näyttää suhteellista aikaa (15min sitten, 2h sitten, 3pv sitten)
- DB: enabled_modules sarake companies-tauluun, role ENUM laajennettu
- Automaattinen migraatio: vanhat admin → superadmin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Priority was missing from the tickets list endpoint,
so colors weren't showing in the ticket table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Priority emails are now per-customer, not per-company.
Each customer can have a list of email addresses that
automatically elevate ticket priority to "tärkeä" when
they send email. Field added to customer form under
"Lisätiedot" section.
Removed separate priority_emails settings from API/rules tabs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reply form:
- Mailbox/sender selection dropdown (choose which email to reply from)
- CC field (auto-filled from incoming email CC, editable)
- Reply templates dropdown (quick insert pre-made responses)
Priority system:
- Three levels: normaali, tärkeä, urgent
- Priority dropdown in ticket detail view
- Priority-based sorting (urgent/tärkeä always on top)
- Visual indicators in ticket list (colored rows, emoji badges)
- Priority emails: per-company email list that auto-sets "tärkeä"
Response templates:
- CRUD management in Settings tab
- Dropdown selector in reply form
- Templates insert into textarea
Telegram alerts:
- Bot token + chat ID configuration in Settings
- Test button to verify connection
- Auto-alert on urgent tickets (both manual and from email fetch)
- Alert on priority email matches
Database changes:
- New tables: reply_templates, customer_priority_emails
- New columns: tickets.cc, tickets.priority
- ALTER TABLE migration in initDatabase()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
finfo_open() is not available on CloudLinux alt-php84.
Now validates by file extension first, and only uses finfo
if the extension is available. Falls back gracefully.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
With MySQL migration, data/companies/{id}/ directories may not exist.
Now creates directory automatically instead of returning 404.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
check_auth was returning branding based on active company with
wrong field name (company_nimi instead of nimi), causing Noxus Intra
to show instead of company name on refresh. Now uses dbGetBranding()
with the request domain, same as the branding endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Users can only log in from domains belonging to their assigned company.
E.g. cuitunet users can only log in via intra.cuitunet.fi.
Admin users can still log in from any domain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Allekirjoitukset tallennetaan users.json:iin (signatures-objekti, avaimena mailbox_id)
- Käyttäjälomakkeessa dynaamiset textareat jokaiselle postilaatikolle
- Allekirjoitus liitetään automaattisesti sähköpostivastauksiin (ticket_reply)
- Esikatselu näkyy tikettivastauslomakkeen alla
- Muistiinpanoihin (ticket_note) ei lisätä allekirjoitusta
- Uusi all_mailboxes endpoint palauttaa kaikki käyttäjän postilaatikot
- check_auth ja login palauttavat nyt myös user_id ja signatures
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
- check_auth always reads fresh company permissions from users.json
- user_update updates session immediately when editing own permissions
- Prevents stale session showing tickets from companies user lost access to
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove temporary data_diag/data_read/data_write endpoints
- Auto-recovery now scans existing company directories if companies.json
is empty or missing (handles git deploy wiping the file)
- Auto-creates config.json for any company dir missing it
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove data/companies.json and data/companies/cuitunet/config.json from git
(tracked data files get overwritten on every deploy, causing data loss)
- Add data/companies/*/ and data/tickets.json to .gitignore
- Migration now auto-recovers companies.json and config.json if missing
(handles case where git clean removes untracked data files)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- tickets endpoint supports ?all=1 to fetch from all user's companies
- ticket_detail/reply/status/etc support ?company_id= for cross-company ops
- Support tab shows all companies' tickets with company badge on subject
- Yritykset button moved from tab bar to header (next to Käyttäjät)
- requireCompanyOrParam() helper for ticket endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous check (directory existence) failed on production because
git pull created data/companies/ from committed config.json, causing
the migration to be skipped while customer data remained in data/ root.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
- Fix tickets API endpoint: add type, customer_name, customer_id, tags fields
- Add tags array to ticket data structure with add/remove UI
- Add tag filter input to toolbar and tag column in ticket list
- Add ticket_tags API endpoint for updating tags
- Add set_tags and auto_close_days actions to auto-rules
- Auto-close check runs on ticket list load, closes expired tickets
- Add tag CSS styles with editable tag badges in detail view
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Auto-rules JS: load, render, save, edit, delete, toggle rules
- Rules UI: Säännöt view with rule list and form
- Bulk actions: checkbox selection in ticket list
- Bulk close/delete endpoints (ticket_bulk_status, ticket_bulk_delete)
- Bulk toolbar with select all, close selected, delete selected
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Closed tickets completely hidden from default view, separate
"Suljetut" checkbox to toggle them with search capability
- Removed "Osoitettu" column, added "Asiakas" column to ticket list
- Customer dropdown in ticket detail view to link ticket to a customer
- ticket_customer API endpoint for linking tickets to customers
- ticket_type changelog label added
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Asiakaspalvelu tab moved to first position in navigation
- Added ticket type field (Laskutus, Tekniikka, Vika, Muu) with
type filter dropdown and type column in ticket list
- Type selector in ticket detail view with API endpoint
- Closed tickets hidden by default (selectable via "Kaikki tilat")
- Käsittelyssä rows highlighted with green background
- Type badges with color coding per category
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Production server doesn't have php-imap extension. Replaced the entire
ImapClient class to use stream_socket_client() with raw IMAP protocol
commands. Supports SSL/TLS, STARTTLS, MIME header decoding, body
extraction with encoding detection, and charset conversion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
IMAP client for fetching emails from asiakaspalvelu@cuitunet.fi,
Freshdesk-style ticket management with status tracking, message
threading, reply/note functionality, and IMAP settings in API tab.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Requires exact match of osoite + postinumero + kaupunki.
No longer exposes addresses, speeds, or any customer data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Production server (PHP 8.4) doesn't have mbstring extension,
causing 500 error on saatavuus endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>