Stop classifying a multipart/related HTML root as an attachment
Every transactional email we send with an inlined org logo arrived in our own /messages viewer with a correct subject and a completely empty body. isAttachment...
Preview samples for the nine opportunity notifications
Without an arm here the admin Email Templates editor renders every placeholder blank, so anyone customising these nine would be editing an empty skeleton. One ...
Preview variables for PHI_ACCESS_ALERT
Without a sampleVariables arm the admin Email Templates preview renders every placeholder blank, so whoever is asked to approve the wording of a security alert ...
Scan the shared MFA repositories
MfaEnrollmentService is a @Service in kamo-shared-library, so the wildcard @ComponentScan("com.kamo") in this application constructs it whether or not this serv...
Merge duplicate kamo key that crashlooped EmailService
The new EmailService pod has been in CrashLoopBackOff since 16e8a05 — 22 restarts, never once started. snakeyaml raises DuplicateKeyException on a repeated top-...
Commit outstanding work in progress
Staged and committed as-is so nothing is left uncommitted in the working tree. 1 file changed, 12 insertions(+)
Harden the kubectl download against flaky egress [skip ci]
dl.k8s.io over the runner's egress intermittently drops mid-transfer: curl: (56) OpenSSL SSL_read: decryption failed or bad record mac which fails the deploy ...
Avatar endpoints; fix unauthenticated reachability and contact tenancy
Adds the mailbox side of sender avatars, and fixes three pre-existing holes this work would otherwise have built on top of. AUTHENTICATION. OTKPreAuthFilter us...
Add missing CampaignController REST endpoints for /api/email/campaigns
The bulk-email workspace/editor call GET/POST /api/email/campaigns etc., but only CampaignService (the @Service) was ever created — no @RestController exposed i...
Remove ambiguous unsubscribe requestMatcher that crashed startup
EmailService mounts two servlets (MVC DispatcherServlet + Spring-WS MessageDispatcherServlet at /services/*), so a bare string requestMatchers( "/api/email/unsu...
Bulk email campaign backend — provider, dispatcher, compliance, realtime
Backend for org-level bulk email campaigns, entirely separate from the everyday email provider so it can't be throttled/blocklisted alongside business mail: - ...
Rebuild to pick up **************** canonical keys
No source change. EmailService bundles kamo-shared-library at build time, so the CANONICAL_KEYS fix (shared-lib c028131) only reaches its runtime self-heal afte...
Sample variables for the LEADS_ASSIGNED template
Without a case here the admin template editor's Preview renders the new template with every placeholder blank, which reads as a broken template rather than an u...
Accept X-***-Token for mobile clients in OTKPreAuthFilter
per-tab session id as X-***-Token (matching **************** When present (and no X-OTK), resolve the session non-consumingly and set the same request attribute...
Support "unblock forever" remote-image consent
Adds a wildcard consent (allowAll / isAlwaysAllowed) so a member can opt to display external images in every message. Reuses the existing consent table via a re...
Inline-CID org logo (SVG->PNG) so it renders in Gmail; remove message content; preserve From-domain case
- FIX (security): notification emails carry no message body — remove messagePreview from template vars, ledger, samples and the settings toggle. - FIX (logo):...
Editor sample variables for missed-message notification templates
Preview samples for MISSED_CHAT_MESSAGE and SUPPORT_TICKET_REPLY incl. raw vs html-escaped sender/title variants used by the canonical bodies.
Microsoft 365 mail via Microsoft Graph app-only (zero per-mailbox setup)
Microsoft 365 mail now reads/sends through Microsoft Graph app-only (Mail.ReadWrite/Mail.Send application permissions) instead of IMAP — one app credential cove...
Stop serializing computed xoauth2 getter that broke MailCredentials Redis cache
MailCredentials is cached in Redis (GenericJackson2Json). The added `isXoauth2()` boolean getter was serialized as a "xoauth2" property but has no field to read...
Route all cloud providers' mail through IMAP/SMTP with OAuth2 (XOAUTH2)
Cloud providers (Microsoft 365, Exchange Online, Google Workspace, Zoho, IceWarp) inherited read/send from **************** but the resolver never populated IMA...
Server-side "display external images" consent
Replaces the client-local (localStorage) remembering of the external-image choice with a durable per-member record. New RemoteImageConsentService (fail-soft rea...
Scope KamoMail mailbox/domain listing to the org's own domains (cross-tenant leak)
SECURITY: **************** ran 'SELECT email FROM virtual_users' (and **************** 'SELECT name FROM virtual_domains') with no org scoping, so mailbox/domai...
Persist selected OAuth provider on callback so it stops reverting to KamoMail
Switching an org to Microsoft 365 (or Google Workspace / Zoho) never stuck: the OAuth callback stored tokens and only flipped status on a pre-existing provider ...
Resolve welcome-email logo from the org theme host, not the apex
Header/footer logos in system emails (welcome/verification) were built as **************** — an apex path that only exists on the Kamo marketing site, so for cu...
Constant-time internal-auth secret compare (timing oracle)
Replace String.equals with MessageDigest.isEqual so response latency cannot leak the X-Internal-Auth shared secret byte-by-byte. Fleet-wide sweep of the copy-pa...
Sample vars for meeting-summary template preview
Adds a sampleVariables case for the new meeting-summary template so the steward preview UI renders realistic content.
Internal endpoint to create/cancel a member's calendar event
POST /api/internal/calendar/events (X-Internal-Auth gated) resolves member -> user -> primary calendar (creating a default if needed) and creates an event. Used...
Fixed public redirect + gateway-forwarded callback
Platform email OAuth (Microsoft 365 / Google / Zoho) had no valid public redirect URI: the redirect was derived from the request host, which in prod is the clus...
Rebuild against gated shared-lib (mlos.intake beans now opt-in; fixes CrashLoop)
Wire mlos-internal-auth (INTERNAL_AUTH_SECRET) into deployment [skip ci]
EmailService's InternalAuthFilter guards /api/email/templates/send + /seed-org on internal.auth.secret, which was unset (fail-closed 503). Share the existing pr...
Return 422 (not 500) when member has no mailbox
listFolders and other read endpoints threw IllegalStateException from MailContext.toMailCredentials() when a member had no IMAP credentials provisioned, which t...
Don't save transactional NoReply sends to a Sent folder
NoReply is a send-only address with no mailbox, but every transactional send still attempted an IMAP append to its Sent folder, producing a noisy AUTHENTICATION...
Self-heal mailbox accounts from app DB (drift recovery)
The app DB is the source of truth for which mailboxes should exist; KamoMail accounts live in the mail server's virtual_users. If the mail DB loses data, mailbo...
Mailbox list API returns UI-shaped ****************
GET /api/email/mailboxes returned the raw entity (providerStatus, lastSyncedAt, no member count). The settings UI reads **************** so status was always un...
Authorize privilege-based mailbox access for read + send-as
resolveForMailbox only granted access via a direct MemberMailbox assignment, so mailboxes surfaced through **************** rights threw NoSuchElementException ...
Migrate to k1m1 (clone+registry+kubeconfig from k1m1, drop k2m1, simple kubectl install)
Rebuild for kamo-shared-library update (esign signer email templates)
Picks up the new canonical templates esign.signer_verification + esign.signer_invite so seedForOrg can seed them on first send.
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.