KamoCRM

Live Change Log

Every feature, fix and improvement, posted as it ships. Nothing is held back for a launch.

17,374
Total Changes
5,891
Features
5,258
Fixes
30
Projects
Filter by project
All Projects17,374AIService242APIService174BillingService157ConversionService110DaemonService137DocsService223ESigService91EmailService568InitializerService329KBService151KlusterServices738MCPGatewayService235MediaService592RAGService79SecurityService1,822TranslateService62VOIPService248VectorService11kamo-apps26kamo-asterisk-support27kamo-capcha17kamo-capcha-widget4kamo-internal8,321kamo-login335kamo-marketing641kamo-nowww20kamo-register213kamo-shared-library1,631kamo-signer-monorepo56kamolos114
Filter by type
All TypesBuild16CI523Chore773Docs3,252Feature5,891Fix5,258Other993Performance165Refactor278Revert23Style42Test159Upgrade1
September 19, 2026
Fixkamo-internal

Show the correct draft batch total before send

Draft batches keep totalAmount at zero until send — it is a post-send snapshot, not a running total — so the compose UI now sums line amounts for the KPI tile a...

kamo·4w ago
FixSecurityService

Normalize memberId when relaying line add/update requests

The browser keeps member ids as strings to avoid IEEE-754 rounding on CockroachDB unique_rowids. Normalize to Long before relaying so the credit lands on the in...

Kamo·4w ago
September 18, 2026
FixEmailService

Aliases and shared-mailbox access name their members as text

GET and POST /api/email/aliases (and /aliases/member/{id}) and GET and POST **************** answered with the entities themselves, whose Long memberId and gran...

Kamo·1mo ago
FixVOIPService

A number's owner travels as exact text, so saving it no longer re-owns it

GET /api/voip/numbers wrote ownerMemberId as the entity's Long. A member id is an INT8 past 2^53, so the settings page read it rounded: the owner was never foun...

Kamo·1mo ago
FixSecurityService

The account view names its primary member

GET /customers/{uid} sent the primary member only as primaryMemberId, while the account view reads a primaryMember object — so its Primary member row read "---"...

Kamo·1mo ago
Fixkamo-internal

An article's version history draws, and names who edited each version

kbservice answers /articles/{guid}/versions with a Spring Page of its entity. The history component read the body as a list and called .map on the Page, so it n...

Kamo·1mo ago
Fixkamo-internal

A face that opens a card has a name for a screen reader

A MemberHoverCard around a face alone was a focusable button with nothing to be named by. It takes an optional label, used only when the trigger has no text of ...

Kamo·1mo ago
FixDocsService

A document's history loads, and names the people on it and on its shares

GET /imaging/history/changes and /history/downloads built each row with Map.of, which throws on a null — and a row with no IPv6 address, no prior data or no mem...

Kamo·1mo ago
Fixkamo-internal

An article's byline names its author, and opens their card

kbservice answers GET /articles/{guid} with its entity, so authorMemberId is a JSON number, and JSON.parse rounds a 19-digit member id. The article route compar...

Kamo·1mo ago
Fixkamo-internal

The Enter that opens a card goes no further

A name's trigger handled Enter and Space but let the key bubble on, so a list around it that acts on Enter itself — the timecard approvals queue opens the membe...

Kamo·1mo ago
Fixkamo-internal

A card opened in a tool window knows who is online

Presence and availability are provided inside AuthedChrome, but the ToolDock — every chat, ticket and social window, and the chats switcher — is mounted above i...

Kamo·1mo ago
Fixkamo-internal

A name with no card to open draws no hover underline

MemberName drew its dotted hover underline even when the surface had no member id, so a plain name promised a card it could not open. The underline now comes on...

Kamo·1mo ago
FixSecurityService

An account note names the member who wrote it, not "System"

GET /customers/{uid}/notes sent each note's authorMemberId but no authorName, and the account view shows a note with no name as written by the system — so every...

Kamo·1mo ago
Fixkamo-internal

A client's message pops its window into the front row, not a strip behind it

Reported 2026-09-17: Ian wrote into his Exec2Exec chat and the desk never saw it pop up; it was found only by going into the Interaction Center. Nothing upstre...

Kamo·1mo ago
September 17, 2026
Fixkamo-internal

The Webinars section reads the lead API that exists

It called /api/webinar/leads/{id}, which MediaService never served (live 404), and a 404 reads to this section as "the feature is off" — so it rendered nothing,...

Kamo·1mo ago
Fixkamo-internal

The chat head menu acts on the person in the chat, not on the window id

A head's id is its window's id (`chat-3`), and the menu read it as the member it was a chat with. So it fetched /api/security/members/chat-3 — a 404 — and with ...

Kamo·1mo ago
Fixkamo-internal

A meeting from a chat window invites the conversation, and one email goes to everyone

Starting a meeting from a conversation window's meet button, or from a chat hexhead's "Invite to Meeting", invited nobody. The dialog closed as though the invit...

Kamo·1mo ago
FixMediaService

The public demo page shows no one's contact details, and a site's key books only its own org

Demo requests from the marketing site come from visitors with no account. That path already needed none: the attendee row is the name and email the form collect...

Kamo·1mo ago
Fixkamo-internal

My Scheduled Webinars and Join Existing read the booking the server actually sends

The Support badge now takes a presenter to My Scheduled Webinars when a session is booked with them (mediaservice 0212445). That tab — and the wizard's Join Exi...

Kamo·1mo ago
FixMediaService

The scheduler lists the org's webinar types, and a booking badges its presenter

/support/schedule-webinar said "No webinar types are currently available." for every organization, however many types it had. The wizard loads its picker from G...

Kamo·1mo ago
FixSecurityService

Short one-time codes can no longer be guessed without limit

Every short code the platform mails or texts was checked with no count: - POST /api/recover/email/verify-code took the 8-hex-character reset code ALONE and mat...

Kamo·1mo ago
Fixkamo-internal

No OAuth client secret in kamo-internal's source; the anonymous token route is gone

**************** assigned the client-credentials secret for four production client ids (kamo:1:crm:internal, kamo:4:kamo:internal, kamo:5:ebonix:internal, kamo:...

Kamo·1mo ago
Fixkamo-internal

Integration forms send only the credentials that were typed

The org CalDAV/CardDAV tab sent all four server fields on every save of an Apple or custom server. The fields never show what is stored, so they were empty, and...

Kamo·1mo ago
FixEmailService

Saving a calendar/contacts integration never blanks or drops its stored credentials

A contact integration's credentialsJson was replaced by whatever a save sent. The org CalDAV/CardDAV tab sends all four server fields (empty — they never show w...

Kamo·1mo ago
FixMediaService

No secret has a literal fallback in code or config; the Janus API secret never goes to a browser

The Janus API, token and admin secrets and the TURN password were committed four times over: as @Value defaults in WebRTCController and JanusService, as default...

Kamo·1mo ago
FixSecurityService

Securityservice never stores a password as typed

Two writers put plaintext into USERS.PASSWORD. Both called User.encodePassword(), which needs a static encoder that only initializerservice ever sets **********...

Kamo·1mo ago
FixSecurityService

Retail store connections are reachable only by their own org's commerce settings managers

The retail provider-config handlers on CommerceMarketController resolved the session's org and then used whatever market and config uid the path named. Update, ...

Kamo·1mo ago
FixMediaService

A Canva connect only returns the browser to the org's own console

POST /api/media/canva/connect-start stored whatever returnUrl the body named, and the OAuth callback on the API host redirects to it after Canva's consent scree...

Kamo·1mo ago
FixSecurityService

The System User acts only inside the organization it was entered into

There is one System User for the whole platform. Platform operators, and support staff holding a grant scoped to a single ticket's organization, enter a tenant ...

Kamo·1mo ago
Fixkamo-login

Send the typed address with the reset code, and forward the caller's address

The reset page sent the 8-character code from the letter on its own, and SecurityService checked it against every account's outstanding reset at once, with no c...

Kamo·1mo ago
FixEmailService

A shared mailbox's access list is only readable inside its own organization

GET **************** called **************** which read the access rows for any mailbox id. Every other access operation (update, delete, grant, revoke) loads t...

Kamo·1mo ago
FixSecurityService

Only an org's owner, its CONFIGURE_SYSTEM members or active god mode can change its settings

PUT /api/security/org/{id} took no request at all. ResourceServerConfig permits every request and APIService relays /api/security/**, so one anonymous request c...

Kamo·1mo ago
FixSecurityService

An OAuth app save keeps its client secret unless a new one is typed; owners' credentials stay out of org JSON

PUT /api/oauth-config/{id} stored whatever arrived under clientSecret. Responses mask the secret, and the edit form sends a blank back while promising "Leave bl...

Kamo·1mo ago
Fixkamo-internal

The provider form never holds the stored API key

AIService no longer returns provider API keys (only hasApiKey and a last-four mask). The edit button used to copy the returned key into the form, so it was in t...

Kamo·1mo ago
FixAIService

Provider API keys never leave AIService, and only MANAGE_AI_SETTINGS can change a provider

GET /api/ai/providers and GET /api/ai/providers/{id} answered with each provider's DECRYPTED API key. The list is what every member's AI chat model picker loads...

Kamo·1mo ago
Fixkamo-shared-library

Keep every credential field out of JSON, and guard the rule library-wide

Follow-up to 034378d2, which covered the columns NAMED as ciphertext. Read-only audits of origin/main in every repository found 61 more fields holding credentia...

Kamo·1mo ago
Fixkamo-internal

Overlays clear the tool windows, scrollbars stack with their layer, and the rest of the shell geometry

What was left after pages stopped painting over the shell. Overlays opened BEHIND tool windows. Hand-rolled modals, menus and toasts named levels inside the sh...

Kamo·1mo ago
Fixkamo-internal

Start a Facebook / Instagram connection through the authenticated connect-start

The Connect button navigated to **************** MediaService trusted both values with no session, so anyone who knew a connection id could bind their own page ...

Kamo·1mo ago
FixMediaService

Only an authorized member can connect a Facebook or Instagram page, and only back to their own console

The Meta connect flow trusted its URL. GET **************** took connectionId and returnUrl from the query string with no session, and state was unsigned base64...

Kamo·1mo ago
FixMediaService

Refuse webhook posts for Discord connections, which only ever receive DMs over the Gateway

Discord DMs reach MediaService only through DiscordGatewayManager's WebSocket, which publishes straight to social.inbound.raw. But every social connection has a...

Kamo·1mo ago
Fixkamo-internal

Pages stay under the nav, the Interaction Center and the tool windows

The same two mistakes as /calendar's, everywhere else they were made. AuthedChrome's content box names no z-index, so a z-index in page code is a level in the R...

Kamo·1mo ago
FixEmailService

A person taken out of a drip stays out

The engine moves on up to 200 due people per drip from copies it read at the start of a pass, up to 25 seconds old by the time each is used. Meanwhile a member ...

Kamo·1mo ago
Fixkamo-internal

The drip enroll dialog finds leads by email

The lead search behind it now matches a lead's email (kamo-shared-library 992569a6, live with SecurityService 5c7319a), so the dialog says so: name, email, comp...

Kamo·1mo ago
Fixkamo-shared-library

A lead search matches the lead's email too

The /leads grid's boxes and the drip enroll dialog send what was typed as search terms, OR-ed across the lead's names, company, vendor lead id and number. The e...

Kamo·1mo ago
Fixkamo-internal

The calendar stays under the nav and the tool windows

/calendar positioned itself over the viewport — fixed at 56/80 with z-index 1000 — instead of filling the content box AuthedChrome gives every page. That box na...

Kamo·1mo ago
Fixkamo-shared-library

Keep every ciphertext column out of JSON, and guard the rule library-wide

Follow-up to 096feaa1 (Organization's GoDaddy credentials were being served by an endpoint that needs no session). A scan of every **************** found fourte...

Kamo·1mo ago
FixSecurityService

Stop GET /org/{id} shipping the GoDaddy credentials, and lock it to this service's mapper

The fix is in kamo-shared-library 096feaa1: Organization.godaddyApiKey and godaddyApiSecret are now @JsonIgnore. That change reaches production only when a serv...

Kamo·1mo ago
Fixkamo-shared-library

Never serialize the GoDaddy key and secret ciphertext

GET /api/security/org/{id} (and /org/domain/{host}) returns the Organization entity itself and answers without a session, and that body carried godaddyApiKey an...

Kamo·1mo ago
Fixkamo-marketing

An unconfigured build stops asking SecurityService for org ""

getHuntOffer fetched the promotion status even with no hunt configuration, so that the attempt would tag every prerendered page site-hunt. With no HUNT_ORG_ID t...

Kamo·1mo ago
Fixkamo-shared-library

People in a paused drip still leave it when their lead moves on

A paused drip's exit rules (status change, reassignment, goal click) are now listened for, so resuming it never sends to someone who should have left while it w...

Kamo·1mo ago

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing