The Opt Out tab keeps its content off the card walls
SettingsView's white card and TabPanel carry no padding; every settings tab supplies its own, and this one did not, so its heading, buttons, figure cards and li...
An address opted out of marketing is not written to by the sales agent either
The agent's email check was topic-less, so an address that had stopped newsletters and campaigns - but was not on the whole do-not-email list - could still get ...
Label every prerendered page site-hunt, so a deploy's refresh reaches it
getHuntOffer returned early when the hunt was not configured, and the build never is, so the build made no fetch and the pages it baked carried no site-hunt tag...
Refresh the site hunt's footer line on every pod after a deploy
exec on deploy/ reaches one replica, and each keeps its own cache, so the other served pages without the line for up to ten minutes after every deploy.
Every hunt window wears the site's own pop-up, not a black box
The signal card, pill, exit panel, console and whisper were flat rgba(8,8,8) boxes in monospace with an off-brand green, and read as something dropped on top of...
Pages and settings tabs fill their width instead of a centred column
Drop the max-width and auto-margin caps that held pages and settings tabs to a slim centred column. Where lifting a cap would leave one column of form fields st...
The organization owner sees the Opt Out tab, its menu entry and its card
A brand-new right is held by nobody the day it deploys; gating only on MANAGE_EMAIL_OPT_OUTS would hide the tab from whoever could grant it. Matches Sales Scrip...
The organization owner can open the opt-out list
A brand-new right is granted to nobody on the day it deploys, so a list gated only on MANAGE_EMAIL_OPT_OUTS would ship visible to no organization. The owner hol...
A background nothing can draw is reported, not a lost batch
The org setup wizard's Backgrounds step resized each picked or suggested image in a loop with no catch. Since resizeBackgroundIfNeeded now refuses, with a reaso...
A saved background shows the member's picture, never the platform's
Behavior & Labeling pointed each tile at the slot's public URL the moment the commit returned, before provisioning had written the slot (it had not even been re...
Show the organization's own backgrounds, as many as it has
The sign-out screen asked for img/bg/1-3.webp whatever config.json's backgroundImageCount said, so an organization with no backgrounds of its own was shown what...
A new organization's folder holds none of the platform's backgrounds, stylesheet or config
Provisioning copied the whole base theme into every new organization's folder, KamoCRM's three sign-in photographs included. They sat at img/bg/1-3.webp under t...
Let the server say whether the viewer sees every organization
/network chose between all-networks and my-networks from the platform-rights context. That read fails closed and stays failed until the page reloads, and a god ...
A god account is shown every organization, wherever it is signed in
GET /org/all-networks - the list behind /network - was gated on the SYSTEM_USER platform right alone, and platform rights resolve only in a top-level-organizati...
Name the sender once at the top of the preference page
With a logo, the name is its alt text and is not written out again beneath it; without one, the name is the header. It was shown, and read aloud, twice.
The opt-out list only names contacts from organization books
A member's personal address book is theirs; the org-wide opt-out list must not become a way to see whose private contacts include someone.
The desk is never a client of itself
Sage and Erik both hold EXEC2EXEC_ACCESS, and each owns organizations of their own. Signed into one, the owner arm of Exec2ExecEligibility gave each a "client" ...
A saved campaign reopens inside its template, and the From is always the bulk sender's
The body is saved between two comment markers inside the finished email, and reopening a campaign puts only that part back in the middle of the template, where ...
Every campaign is sent as the org's bulk sender, and its From never pauses it
A campaign's own from_email/from_name are no longer read: the From is always the address and name on Settings > Email > Bulk Email Sender (else the org's NoRepl...
Startup checks for the one-address-per-campaign index instead of creating it
EmailService ran CREATE UNIQUE INDEX on every startup. DDL on this cluster costs every service about fifteen minutes of "schema version mismatch", too much to r...
Read the platform's hex secret as hex, and stretch a short key instead of refusing it
JWTUtils decoded security-service.*** as Base64 only. The platform's secret is 64 hex digits (32 bytes), which Base64 turns into 48 meaningless bytes; those wer...
The campaign editor's Recipients and Send steps fill the width instead of an 860px column
Review fixes to the provider blob, delivery reports and test send
The provider blob is always written in a transaction of its own, so its lock query stays the first statement and a lost lock race can be retried even when a cal...
Review fixes for the bulk sender, warm-up and pacing banner
A pass over everything the bulk sender and warm-up screens are built from, fixing what it found: - a warm-up poll that started while a write was on the wire co...
A from the platform relay would refuse pauses the campaign instead of failing its recipients
Failing the recipients made every one of them contacted, so once the From was fixed the campaign could never send to those addresses. The send path now checks t...
Email settings redirect lists its hook dependencies
The rights check that sends a member without MANAGE_EMAIL_SETTINGS back to /settings ran in an effect that listed only `loading`, so the linter flagged the miss...
The platform relay is recognised by one host-and-port check everywhere
Refusing an off-domain From matched the relay by host and port, while the warm-up's delivery tracking and the test send's advice matched by host alone, so a pro...
Live campaign progress reaches browsers on every replica
The STOMP broker is in-heap per pod and progress is raised on whichever pod holds the dispatch lease or received a delivery report, so browsers on the other pod...
The bulk sender tab fills the width it is given
The tab sat in a 1120px column centred in the settings card, so on a wide screen most of the card was empty margin around a narrow form. The column is gone, alo...
This relay only sends as kamocrm.com
Anything in mynetworks (every pod, and the LAN) could relay through 47.181.8.84 as any domain, which receivers treat as spoofing and charge to this IP; that is ...
The delivery-events sidecar drops a batch EmailService rejects as invalid
A 400/413/422 means the batch itself will never be accepted; retrying it forever would hold back every result queued behind it. It is logged and dropped. 401/40...
The smtp envelope sender is set to the bare from address
Campaign mail now carries a display name in its From, and the relay it goes through accepts only its own sender domain, judged by MAIL FROM. mail.smtp.from is n...
A relay that never signs in counts as a configured bulk sender
/marketing/email let an organization send campaigns only once its bulk provider had a stored password. The platform relay listens on port 25 with no TLS and no ...
Recipient grid fills name, source and error from either row shape
The campaign recipient grid read name, sourceType and errorMessage from rows that only carried email, status, sentAt and lastError, so three of its five columns...
A missing mailing address no longer blocks sending
The preflight treated an org with no address on file as an error and kept Send and Schedule disabled. The address still goes in the footer when there is one; wh...
A missing mailing address no longer blocks sending
assertSendable refused to schedule or send a campaign without a physical address. The org's address still goes in the footer when it has one on file; when it ha...
A hold'em invitation is gated on the right to play hold'em
HOLDEM_INVITE was in neither the gated nor the ungated map, so it shipped ungated and failed the test that exists to catch exactly that.
A line break in a sender's display name can no longer start a header
Jakarta Mail encodes commas, quotes and non-ASCII in a display name but passes a raw CR/LF through, so displayedAs now flattens control characters to spaces bef...
Keep hello.kamocrm.com off this relay, and stop three errors on every start
- A @hello.kamocrm.com sender is refused relay here with a 4xx, so bulk mail can only leave through postfix-bulk; delivery to our own domains is unaffected....
The NoReply recorder names the constructor Spring should use
It has two, the second for tests, and with neither marked Spring picks neither: the context failed with "No default constructor found" and took EmailSmtpService...
The campaigns grid read counts the API never sent
EmailService's CampaignDTO carries a campaign's counters flat (totalCount, sentCount, failedCount, suppressedCount, bouncedCount, queuedCount), but every screen...
The launch bar ends at the form column, clear of a docked chat window
On /network/create the readiness meter and the Launch organization button sat in a bar across the whole page, under the brand preview too - exactly where docked...
An echo of the censored English is not a translation
translatedLocales compared each translation with the English title as stored. The translator is given the censored title (ChangelogSanitizationService masks sec...
The General tab counts what the Organizations tab calls Active
6c8d789 moved the platform overview's organization count onto findAllLive(), which also drops orgs created by synthetic (is_fake) accounts β so the General tab ...
Binders and Uploads read as live buttons in the org's brand
The two tabs looked disabled because they were: a MUI Tab with no <Tabs> parent defaults to textColor="inherit", which draws the whole tab at 60% opacity unless...
Order sitemap <url> children as the schema does, and give each chunk one address
The sitemap XSD is a sequence: loc, lastmod, changefreq, priority, then extension elements. The hreflang links were written straight after <loc>, which Google t...
Count the files a document keeps only as old versions
A category that keeps versions holds every earlier file of a document in img_versions, each on its own content-addressed file. The storage meter, the quota and ...
Sharing a document works again, as someone who can read it
The share dialog sends a document id as a string β an img id is an int64 past 2^53, which a JSON number would round β and createShare cast it to Number. Every s...
The rim's lead current stays white-hot all the way round
Its gradient was pinned to the hexagon's box rather than travelling with the arc, so for a third of every lap the current was gold on the gold rim and simply va...
A window's scrollbars no longer show through the window on top of it
Maximizing a tool window left a column of scrollbar buttons from the window behind it floating in the middle of the pane, and two overlapping floating windows s...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.