Re-verify domains already marked SSL-confirmed, and heal them
findAwaitingVerification filters confirmed domains out by design, so once ssl_confirmed was set nothing ever looked at that domain again. That was fine while th...
Make post-commit org setup actually write, and heal the orgs it missed
A @Transactional method called from **************** does not open a transaction of its own. Spring fires those callbacks from processCommit BEFORE cleanupAfter...
Confirm SSL only when every org host has its own certificate
Certificates are minted one per FQDN -- a single dnsName each, so the leaf CN matches the hostname the browser connected to -- and auto-cert works through an or...
Serve frame media ourselves, with Range
Every photo rendered as a broken image. The URL pointed at MediaService's **************** which I took for a general imaging proxy because it spoke HTTP Range....
Frame and media endpoints, and seed the new rights
Self only, and enforced in the QUERY. Every read and write resolves the member from the session and every repository call takes that id, including the single-fr...
Stamp last_login so "Last Login" stops reading Never
Nothing in SecurityService has ever written users.last_login. The write lived in the retired AuthenticationService and was not carried over when authentication ...
Restore the status endpoint the frontend has been polling
kamo-internal polls GET /api/security/session/god-mode once on mount and every 60s thereafter. That endpoint was removed in 9c70cb7 along with the rest of the t...
Rebuild against kamo-shared-library 48cde37
Picks up MANAGE_ORG_MASTER_NOTE, the right that guards "Our Master Note". SecurityService is what enumerates RoleRightType for the role, job-title and departme...
Drop the universal seed; the timecard widget follows MANAGE_TIMECARDS
UNIVERSALLY_SEEDED_RIGHTS is removed entirely. It existed only because the timecard widget had no parent right to inherit from, and now it has one — so the widg...
Seed the mail and lead widgets, and add a universal seed for the timecard one
The mail and lead widgets follow their data rights exactly as the calendar ones do — ACCESS_MAIL and VIEW_LEADS — so a holder gains no data they could not alrea...
Seed the calendar widgets to everyone who can already read the calendar
Both widgets show a member exactly what /calendar already shows them, so a calendar reader gains no data they could not reach — which is what makes this a safe ...
Annotate the member roster with its chat policy verdict
SecurityService serves the roster the chat UI is built from, so it has to answer with the same verdicts MediaService enforces with -- one shared evaluator, or t...
Ask EmailService to back-fill a lead's past e-mail
Implements the shared library's LeadEmailBackfillTrigger, so ticking "Associate Past E-Mails w/ Lead" on a lead save reaches the only service that can read mail...
Accept a reservation raised for another agent
POST **************** now honours onBehalfOfMemberId, gated on EDIT_OPPORTUNITIES — the right that gates managing opportunities on the reserved list, and alread...
Publish Hibernate statement counts to Prometheus
/actuator/prometheus already carried jdbc_* and hikaricp_* but no hibernate_*, because Spring Boot 3 only auto-configures those metrics when **************** is...
Delegate AvatarObjectPaths to the shared library
MediaService now names avatar objects too — the support chats list shows the requestor's photo, and a support requestor is in somebody else's organization, so n...
Return each member's accepted-today count per product
Manage-Credits shows Max Daily Spend but nothing about how much of it is used, so a manager could not tell whether a member was one lead from their cap or had n...
Stop cutting note bodies off at 500 characters in the timeline
The All tab of a lead's communications rendered a note through LeadCommunicationMapper, which capped the body at 500 characters — with no ellipsis and no flag, ...
Report leads available for products with no allotment
/manage built its whole response by looping over allotments, calling countAssignablePool once per row. But the Manage-Credits grid lists products from the vendo...
Stop scanning every market x product after the answer is known
/leads/available-summary returns three things — hasAcceptable, hasAcceptableCredit and one example product — but visited every market x product pair regardless,...
Mint a System User session for a support agent's open ticket
enter-as gains a second reason to say yes. SystemUserEntryPolicy turns the caller's *** into the facts the shared SupportSystemAccessResolver takes, and that re...
Count in the database instead of hydrating every commit
GET /changelog/public/stats loaded all 16,571 commit logs as entities and tallied them in a Java loop to produce two small maps and a total. It takes no authent...
An opt-in probe that executes the grid's SQL, not just its HQL
/leads went down on 2026-08-20 with 'missing FROM-clause entry for table a2_1' and no test caught it, because none of them could: the library compiles against H...
Page the grid endpoint and take the PHI audit write off the request thread
GET /api/security/leads returned every lead in the organisation. It now takes page/size/sort plus the filters the grid actually uses, and returns a page with a ...
Settle each backlog payload as it is processed
processBacklog mirrored the scheduled job's two defects: it mutated payload statuses in memory and saved them in one batch at the end, and it saved the whole en...
Never fail a submission because its counter update lost a race
storePayload no longer bumps the endpoint's received counter; the receive controller now calls recordReceipt separately, in its own transaction, and swallows th...
Rebuild against kamo-shared-library 811db57
Picks up the createLead fix that moves the pool-availability recount to afterCommit. Before it, a read-after-write in the lead's own transaction hit YugabyteDB'...
Map companyName so a spreadsheet can carry the business name
setDirectFieldOnCreateRequest had no companyName case, so the field was unreachable from the manual-import wizard even though CreateLeadRequest carries it and L...
Accept the discount* signup fields, keep the mrt* ones working
The register site now sends discountVisitorGuid / discountCode. Both names are read, new first, because the two services deploy independently — for the minutes ...
Publish signup and org-created for tracked visitors
The register site now forwards the marketing visitor GUID and tracking code in the request body — not a header, because the proxy strips Cookie and the ingress ...
Enforce is_fake, and close the holes that let an unattended signup in
Two halves of one incident. An account registered, verified an address at a disposable provider, took an auto-login session and created five organizations in th...
Let a member give up their own membership
The network page has offered "Unsubscribe" since it was written. It opened a confirmation dialog and then said the feature would be implemented soon, because th...
Make the verification sweep's DNS upgrade reachable
DomainVerificationWatcher gated on **************** but **************** only ever answers ok/pending/error/na — it has never returned "verified". allVerified w...
Restore media as a required DNS alias so its card can verify
media.<domain> backs MediaService realtime websockets and is live in Traefik, auto-cert and the /setup/dns studio catalog, but it was dropped from KnownAliases ...
Stop reporting a missing column as a missing table
Four controllers each rewrote ANY message containing "does not exist" into "Database table X does not exist. Please run KamoInitializerApp to create the schema....
Delete the unauthenticated /api/security/roles/test stub
A reachability probe that returned "SecurityRoleController test endpoint is working" to anybody. Nothing calls it — no reference in any service or in kamo-inter...
Close two unauthenticated endpoints reachable from the internet
SecurityService is anyRequest().permitAll() with @EnableMethodSecurity absent, so every @PreAuthorize is inert and public is the default; APIService relays /api...
Per-member SSO credentials and a preflight that explains failures
Linux is gated on an enabled provision rather than god, and served with the member's own credentials. The connection is omitted from the token entirely when the...
Dev machine service and controllers
Username derives from the member ACCOUNT email, not the TeamMember work email — a work address can sit on another domain and would silently produce a different ...
HTTP client for the dev machine provisioning agent
health() swallows transport failures and answers false so the SSO preflight can return an actionable 503 rather than a 500.
AES-GCM secret codec and POSIX username derivation
Codec is deliberately reversible — RDP auto-login needs a real password — and uses GCM so a tampered or wrong-key row fails loudly rather than decrypting to noi...
Send int64 ids to the browser as strings, without touching sessions
CockroachDB unique_rowid() ids are 19 digits, past Number.MAX_SAFE_INTEGER, so an id sent as a JSON number arrives in the browser with its low digits rounded aw...
Delete the dead Long-as-string config and pin why it must stay dead
JacksonConfig registered a **************** serializing Long as String -- the standard guard for CockroachDB ids, which run past JavaScript's MAX_SAFE_INTEGER. ...
Stop rejecting request fields the DTO does not have
Declaring an ObjectMapper bean takes binding away from Spring Boot's auto-configured one, and a hand-built mapper carries Jackson's defaults rather than Boot's....
Resolve the KamoMeet logo overlay into config.json
KamoMeet is a Meet fork with no access to OrgContext, so it learns org branding from the theme config.json this service bakes. The org stores an overlay TOKEN; ...
Rebuild against the shared-lib loading_logo_overlay column
No source change. CI clones kamo-shared-library at build time, so Organization.loadingLogoOverlay is only mapped once this rebuilds — until then the generic PUT...
Narrow the member search to holders of a given right
The lead assignment picker needs the directory to return only people who can actually work a lead, so /team-members/search takes a requiredRight. An unrecognise...
Stop failing a branding save over compliance flags it never sent
PUT /org/{id} derived the age ranges and the three ATF flags from the stored row whenever a request omitted them, then asserted all five against the applied sec...
Rebuild against the shared-lib home_logo_overlay column
No source change here. SecurityService's CI clones kamo-shared-library at build time, so it only maps Organization.homeLogoOverlay once it is rebuilt — and unti...
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.
