A hot reassign requires its call note on the server, not only in the dialog
Point loan officers at the card they will actually find — Lender credentials
Both the MeridianLink and the Arive 'officer not linked' refusals named cards that no longer exist under those titles.
The forgot-password hint is the account's address, whatever it is
d7ff5ed called the address on the user account "personal" everywhere: in the 409's message, the response field and the class. It is not always personal. An admi...
Gift cards take the Discounts tab's pricing rights
Listing gift cards, issuing one and editing one (including its balance, which the shared library sets again as of the companion kamo-shared-library commit) chec...
A member's official title and status need member security too, on their own record
Department and job title already needed MANAGE_MEMBER_SECURITY (or an open god window) on /member-security, your own record included. The rest of the Position c...
CommerceMarketController's retail sub-resources are org-scoped
CommerceMarketController's get-one/update/delete handlers under /retail/... called RetailService methods that took no orgId (bare findById/deleteById) - a same-...
Drop 4 newly-guarded handlers from the unguarded-endpoints ratchet
**************** caught the previous commit: **************** and **************** now resolve a session (getCachedOrganizationId, in each handler's own body), ...
Scope roles, member access and profile writes to the caller's org
Five gaps let a signed-in member reach outside their own organization, or reach a colleague's account, with no right check: - **************** resolved no sess...
Forward the actor when relaying a commission line
addLine/updateLine relayed memberId (normalized to Long in 789c544) but never who was making the call — unlike openDraft, send, voidLine and every Stripe-config...
Forward subjectMemberId and role so TimecardService can verify punch ownership
**************** resolved the caller's role against a CLIENT-SUPPLIED subjectMemberId (resolveRole -> EMPLOYEE whenever actor==subject) but never forwarded that...
Adding people and member security need their rights
POST /members/create, /create-team-member and /bulk-create, and GET /members/lookup-user, now require MANAGE_MEMBERS or an open god window. They checked only fo...
Gate the API on the app, not only the screen
The settings page and the nav option both check organization.isHostedComputers, and until now that was the whole gate. AppAvailabilityInterceptor never mapped /...
Intake endpoints show exact received/imported counts from the intake ledger
The Lead Intake settings list showed total_received / total_processed / last_received_at straight off the endpoint row, where they were bumped once per payload ...
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...
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 "---"...
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...
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...
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 **********...
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, ...
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 ...
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...
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...
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...
Retry public reads the database aborted with 40001
Every DDL bumps the YSQL catalog version, and a transaction that began on the old one fails with "catalog snapshot ... invalidated: MISMATCHED_SCHEMA" (SQLSTATE...
Take kamo-meet and kamo-analytics off the public changelog
Both names leave changelog.public-projects. Every public read goes through that one list, so the marketing site's /changelog stops showing them everywhere at on...
The id resolver never hands a campaign an address the member can't read
Resolving lead ids read each address through the lead masking DTO and skipped only blank ones. Masking now obfuscates instead of blanking ("s*****@gmail.com"), ...
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...
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...
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 ...
Quote and borrower-portal links only name a live domain
QuoteEmailClient settled for any active domain, verified or not, so an org still setting up its white-label domain had quote links mailed to sign.<that domain>....
An organization's .svg names show its own art, not the platform's
A new organization's folder is seeded from the base theme, so it starts out with KamoCRM's art under img/logo-full.svg and favicon/favicon.svg. An organization ...
An org without the app must not accrue achievements either
The award gate asked for VIEW_ACHIEVEMENTS and stopped there. Rights are not entitlement-filtered, so that right stays granted — and keeps answering true — in a...
Refuse to award a member whose security type excludes it
AchievementController checks VIEW_ACHIEVEMENTS on all four of its endpoints, and that read like the rule being enforced. It was not: it is the rule enforced on ...
The same-commit-rebuild guard could never fire, so every dispatch failed
Rebuilding this service without a commit of its own — a workflow_dispatch, a re-run, or a kamo-shared-library change it must pick up — has been failing at deplo...
A pane lock survives the editor alt-tabbing away
The client heartbeats its pane lock every 15s and the sweeper released any lock unheard from for 45s — three missed beats, which reads like a generous margin an...
The baseline award was two transactions, not one
`ensureBaselineFor` calls `ensureBaseline` on `this`, and Spring's transaction advice is a PROXY — a self-invocation does not pass through it, so the inner REQU...
A callback can carry the link to the call
The lead page composes a callback in the calendar's own dialog, and every field that dialog collects is meant to survive the trip through here. meetingUrl did n...
Wire the god guard into the identity-rights test's policy
UserAccountEditPolicy took a third constructor argument and this test still built it with two, so test-compile failed — and CI runs `mvn package -DskipTests`, w...
Keep the dispatch's status write in step with the denial reason
Two services move a system bug's status, and only one of them knew about the new denial_reason column. A dispatch applying IN_PROGRESS to a report that had been...
Log a referral code that arrives with no visitor guid
A signup carrying a marketing code but no visitor guid had its referral dropped in complete silence — the branch that publishes the attribution event is gated o...
Publishing an application opens its chat key to the page it is on
The support widget on a published application loaded with Kamo's default config instead of the org's: it auto-opened on desktop with auto-open turned off, wore ...
Close the last two catalog-bump gaps, and stop echoing exceptions
Two reads and nine response bodies, both halves of the same report. SessionRefreshController loaded the member one statement before the rights read that was fi...
Stop handing the database's own error text to whoever is signing in
The catch-all at the end of login() put e.getMessage() in the response body, and that body is rendered verbatim on the sign-in screen. On 2026-09-05 the excepti...
Send the application receipt after the commit, not inside it
The submit handler is @Transactional, and it was calling EmailService inline — blocking HTTP into blocking SMTP with a 30-second read timeout, while holding a d...
Stop stranding phones on a rotation they never received
KamoMobile was signing itself out at random, most visibly across app updates, and the exchange endpoint was doing it. Three separate ways: The secret rotated F...
Merge the digest output instead of declaring a second outputs block
The previous commit added an `outputs:` key to a job that already had one. Forgejo's parser rejects a duplicate mapping key and skips the workflow entirely, so ...
A rebuild of the same commit deployed nothing and reported success
The image is tagged with the commit SHA, so rebuilding the same commit produces an identical image reference. `kubectl set image` then changes nothing, the Depl...
The lockout warning promised the wrong rung, and the wrong count
The strike meter on the sign-in screen was telling people something the server then did not do. tierFor starts the five-second delay at the SIXTH failure, but a...
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.
