Webmail parity (Community vs Enterprise)
Community's webmail and Enterprise's webmail (HiTechCloud Webmail, the webmail module,
the hitechcloudmail repository's webmail/ tree, installed by
hitechcloudcli webmail) are different applications. The owner's rule
for this pairing is unconditional: Enterprise is a superset. Whatever
Community's webmail gives an end user, Enterprise's must give too — an account
upgrading from Community must not find a single thing missing.
This page is the gap audit against that rule: what a stock installation of
Community's webmail gives an end user (the mail client itself, plus the
settings a user relies on day to day), checked against what is actually
implemented in hitechcloudmail/webmail's source — not assumed, not inferred
from a feature's name, but read in the code. The table is kept current by
whoever closes a gap: closing one flips its verdict and its "where it lives"
column in the same change that closes it.
Summary
| Verdict | Count |
|---|---|
| Present | 17 |
| Partial | 2 |
| Missing | 2 |
| Total items audited | 21 |
The table
| Item | Community's webmail | Enterprise's webmail (HiTechCloud Webmail) | Verdict | Where it lives / what is needed |
|---|---|---|---|---|
| Folder management — create, rename, purge | Yes | Yes | Present | hitechcloudmail/webmail/backend/src/routes/mail.js (POST /folders, /folders/rename, /folders/empty), backend/src/routes/accounts.js (GET /:id/folders) |
| Folder management — subscribe/unsubscribe | Yes (true IMAP SUBSCRIBE) | Hide/unhide only (a client-side preference, not an IMAP subscription) | Partial | frontend/src/components/Sidebar.jsx (folderMenu.hide/unhide). A real IMAP SUBSCRIBE/UNSUBSCRIBE would only matter to another IMAP client sharing the same mailbox — lower priority than the items below, left open |
| Identities with signatures (plain and HTML) | Yes | Yes | Present | account_aliases table (reply_to, bcc, signature) plus the primary account's own signature column; frontend/src/components/SignatureEditor.jsx, frontend/src/components/AdminPanel.jsx (Accounts tab); HTML signatures pass through services/emailSanitizer.js |
| Address book / contacts, with groups | Yes | Yes | Present | contacts, address_books, contact_groups, contact_group_members tables; backend/src/services/contactGroups.js; frontend/src/components/ContactsPage.jsx (group filter chips, per-contact group toggles) |
| Contact import and export (vCard / CSV) | Yes | Yes | Present | backend/src/routes/contacts.js (GET /export, POST /import), backend/src/utils/vcard.js, backend/src/utils/csv.js |
| Message search, including in a selected folder and by header | Yes | Yes | Present | backend/src/routes/search.js (parseSearchQuery): from:, to:, subject:, has:, is:, after:, before:, in:<folder> operators plus free text |
| Threading and sorting | Yes | Yes | Present | backend/src/routes/mail.js (thread-grouped inbox, threadId); list sort order in frontend/src/store/index.js |
| Filters / Sieve | Yes (enforced by the mail server itself, so it runs even while the client is closed) | An in-app rule engine only — runs while the webmail's own process is polling the mailbox | Partial | backend/src/routes/rules.js, backend/src/services/inboxRules.js, backend/src/services/ruleForwarder.js. Real parity needs server-side Sieve (ManageSieve) enforcement, which lives with the mail server (Dovecot/Postfix), not in this repository — flagged for a follow-up round scoped to hitechcloudcli's mail module |
| Vacation / autoresponder | Yes | No | Missing | No route, service or UI exists. Same dependency as Sieve above: needs MTA/ManageSieve-level infrastructure outside this repository |
| Spell check | Yes (browser-native) | Yes (browser-native) | Present | The compose editor's contenteditable surface (frontend/src/components/ComposeModal.jsx) uses the browser's own spellchecker, the same mechanism most webmail clients rely on |
| Message-list preferences (layout, preview pane, page size) | Yes | Yes | Present | frontend/src/layouts.js, frontend/src/components/AdminPanel.jsx (Appearance › Layout tab), mailflow_page_size preference |
| Composing options (HTML/plain default, reply quoting, forward as attachment, save-to-sent, drafts autosave) | Yes | Yes | Present | plaintextEmail preference; replies always quote the original; forwarding preserves original attachments; sentCopySaved tracking in backend/src/services/outboundMail.js; frontend/src/utils/draftAutosave.js |
| Attachment handling and inline images | Yes | Yes | Present | Core message compose/view path throughout backend/src/routes/mail.js and send.js, and frontend/src/utils/inlineImages.js |
| Keyboard shortcuts | Yes (fixed set) | Yes (customizable) | Present | frontend/src/utils/defaultShortcuts.js, frontend/src/utils/shortcutBus.js, Settings › Shortcuts tab |
| Printing | Yes | Yes | Present | handlePrint in frontend/src/components/MessagePane.jsx |
| Message source ("view source" / "show original") | Yes | Yes | Present | GET /api/mail/messages/:id/source (backend/src/routes/mail.js, imapManager.fetchRawSource); reachable from the message toolbar, the mobile "more" menu and the right-click menu |
| Mark-as-read behaviour | Yes (immediate / on-open-delay / manual, configurable) | Yes, same three modes | Present | markReadBehavior / markReadDelay preferences, frontend/src/utils/gtd.js |
| Delete-to-trash vs purge | Yes | Yes | Present | A normal delete moves a message to Trash; emptying a folder or a bulk delete from Trash/Junk expunges it — backend/src/routes/mail.js |
| Interface language | Yes | Yes (10 languages) | Present | frontend/src/locales/*.json, Settings › Appearance › Fonts and Language |
| Timezone for displaying message dates | Yes | Yes | Present | New "Display timezone" preference (this round): frontend/src/utils/formatDate.js, Settings › Appearance › Fonts and Language |
| Changing the mailbox password | Yes | No | Missing | The webmail's backend process runs unprivileged and only ever speaks IMAP and its own database — it has no path to change the system/Dovecot password. Needs a privileged system-level helper outside this repository (candidate: a hitechcloudcli mail-module command that a settings page could call) |
| Per-identity Reply-To / Bcc | Yes | Yes, on every identity except the primary one (same scope the existing Reply-To field already had) | Present | account_aliases.reply_to / account_aliases.bcc, applied at send time in backend/src/services/outboundMail.js (resolveIdentity, mergeIdentityBcc) |
| Responsive / mobile layout | Yes | Yes | Present | frontend/src/hooks/useMobile.js and mobile-specific branches throughout frontend/src/components/; native mobile/desktop shells under frontend/packages/ |
What was carried over from Community, and how
A mailbox's Community-edition data (contacts, contact groups, sender identities and their signatures, and the interface language) is copied — never moved — into its Enterprise data the first time that mailbox signs in to Enterprise's webmail on a server where Community's mail-client database is still reachable. Community's own database is never written to: a customer who goes back to Community's webmail finds it exactly as they left it. The import is idempotent (skips anything that already exists here, matched by address), runs at most once per mailbox, logs what it did, and never blocks or fails the sign-in it runs alongside.
See hitechcloudmail/backend/src/services/legacyImport.js. It activates only
when LEGACY_WEBMAIL_DB_URL is set in that service's environment — wiring
that env var from wherever the Community installer records its own database
connection is follow-up work for the installer round, not this one.
What is left open, and why
- Mailbox password change and server-side Sieve filters /
vacation-while-offline both need something outside
hitechcloudmail's own process: a privileged system helper for the former, mail-server (ManageSieve) enforcement for the latter. Both are flagged above rather than built here, so the gap is visible instead of silently accepted. - True IMAP-level folder subscription is a smaller gap: Enterprise's webmail already gives its own users an equivalent (hide/unhide), and the difference only shows up for a second IMAP client sharing the same mailbox.
Related
- Editions and modules — how a module (like
webmail) is installed and gated.