A carrier-only organization can hold text threads again (SITP CARRIERSMS)
VOIP_CONVERSATIONS.INSTANCE_ID was NOT NULL in production, although the entity and **************** both say an org that texts through a carrier and runs no pho...
An MMS part is stored in one transaction of its own (SITP MMS)
Live check in sp00verify: the picture was fetched and its object written, then the dat's final 'published' save failed (JpaSystemException) because the backgrou...
The MMS part claim names its states as parameters, so Hibernate 6.2 can read it at boot (SITP MMS)
8eda899's deploy never rolled: Spring Data validates every @Query at startup and Hibernate 6.2 cannot interpret a nested enum's FQN literal **************** so ...
A closed god-mode window is closed here too (shared SessionPlatformFacts reader)
Seventeen VOIPService gates (CallController, the VoIP admin controllers, the SMS inventory and bulk-text controllers, DoNotContactController, RecordingAccessSer...
One's own text numbers need the Phone tab's rights, not a bare session (SITP TP11)
ACCESS_VOIP, or MANAGE_EXTENSIONS / MANAGE_VOIP_SETTINGS: the rights settings/member opens its Phone tab on, so nobody who sees the card today loses it.
The members' text-template door refuses flat {error, code, reason} (SITP TP11)
The shape every member-facing VOIPService refusal has, so the Tool Plane and the browser read the reason without unwrapping a nested object.
Seal member VoIP credentials at rest with PlatformSecretCipher; re-seal legacy rows at boot
**************** held each member's access token, refresh token (Teams, RingCentral OAuth) and RingCentral JWT assertion exactly as the provider issued them. Ev...
/api/voip/webhook answers a form post 415 and a non-JSON body 400, never a silent 200
A form-encoded post (Twilio, Sinch, Vonage pointed at the wrong address) fell into readTree(), failed, and was answered 200, so the carrier never retried and th...
A FreePBX voicemail deleted on the PBX stops counting on the phone badge
A deleted message is just absent from its mailbox's listing, so the sync never touched its row again and it stayed unread, badged for good. A row whose mailbox ...
Marking a FreePBX voicemail heard reaches the phone server, and the badge follows at once
A FreePBX message id is mailbox/msgId, so PUT /voicemail/{id}/read never matched a route for it and the PBX was never told: the message stayed in INBOX and the ...
A re-read call keeps the member it was first credited to
CallLogIngestService.ingest set the member (and extension) on every re-read of a settled CDR, resolved from whoever holds the extension now. When ext 7900 passe...
The JustCall contact import finishes β paced, resumable, and no longer skipping pages
Harmony Home Loans' import had never once completed (no JustCall book or integration exists for any member). Three defects: 1. One burst per tick: it read ever...
JustCall calls are credited to the agent who took them, and Sales Dialer calls sync
Checked against Harmony Home Loans' JustCall account (read-only GETs): the newest 100 of its 1,058 /calls match PHONE_CALL_LOG one for one, so the ordinary log ...
The phone badge counts voicemails in your own mailbox, not the whole phone server
The nav phone icon's voicemail line counted every unread message on the member's phone server **************** on the premise that the softphone's Voicemail tab...
A shared voicemail box tells only members who manage the phone server (SP98 T26, final review M-2)
The box's list, audio, read and delete answer only MANAGE_VOIP_SETTINGS (or a god-mode window), and Settings' picker offers only those members, but SharedVoicem...
An AI member's line has an outside-calls switch like anyone's, so one hired while new extensions were denied can be allowed (SP93 final fix)
V12 (PUT **************** no longer refuses an AI line with 409 AI_LINE. A new AI line starts as the phone server's setting for new extensions says (SP93-T5-1),...
Recordings and voicemail audio are written, not refused with a 500
The recording and voicemail audio endpoints are declared ResponseEntity<?>, because they also answer JSON, and returned a StreamingResponseBody lambda. Spring p...
Recordings and FreePBX voicemail play: the pod reaches MinIO
VOIPService streams every call recording and every FreePBX voicemail in Settings out of MinIO, but it never configured MinIO: the shared MinIOConfig defaults ap...
A FreePBX address is judged when it is set or moved, and amiPort must be a port
The FreePBX settings form sends back every field it shows. Judging each submitted baseUrl and amiHost refused K1M1, whose two addresses are cluster-internal bec...
KamoPBX users get the password Kazoo requires, and no provider token is ever stored
Kazoo refuses a user that has a username and no password (400 data.password.required), so every KamoPBX extension and AI line failed; Luna's hire fell through t...
Settings voicemail plays a FreePBX message from its paired upload
Settings -> Phone -> Voicemails plays each row through /voicemails/{id}/audio, which asked the provider for the audio. FreePBX serves no voicemail audio over an...
Phone OAuth hops return the platform's members to internal.kamouniverse.com
kamouniverse.com is the platform's primary apex (kamo-shared-library 0e8cf90f). Sign-in ranks it first for the platform organization, the one organization holdi...
Read JustCall voicemail with INCOMING_VOICEMAIL, and file each under its agent
JustCall answers call_type=VOICEMAIL with 400 ("call_type must be one of ... INCOMING_VOICEMAIL"), so not one of the 241 voicemails on the JustCall account ever...
A PBX ring event rings only members of the key's own org
APIService vouches for the API key's org in X-Org-Id and takes the phone server id from a header the key holder writes. The ring seam ignored the org, so any ke...
Store inbound RingCentral texts, and stop re-registering live JustCall webhooks
RingCentral: the SMS subscription was the bare /message-store filter, whose notifications are a change summary with no message in it, and the reader looked for ...
Read a FreePBX sweep's mailboxes over one manager session
The voicemail sweep runs inside syncInstance's database transaction and asked FreePBX extension by extension, each over a fresh AMI connect and login. A manager...
Read FreePBX voicemail over the Asterisk Manager Interface
FreePBX's API has no voicemail messages: its voicemail module serves mailbox settings only. FreePBXProvider.getVoicemails GET /admin/api/api/rest/voicemail, a r...
Attribute outbound external calls to the extension that placed them (cnum)
Mint a RingCentral webhook verificationToken RingCentral accepts
RingCentral refuses a deliveryMode.verificationToken longer than 32 characters with CMN-101 "Parameter **************** value is invalid" (measured against the ...
Only verified RingCentral webhooks are processed; calling needs a seat
The legacy path that processed a RingCentral call or SMS event with no instanceId, trusting the payload's own to-number, is removed together with its 2026-10-13...
Pin kamo-shared-library 1.6.1, the only version that exists
The library moved to 1.6.1 and this service still asked for 1.6.0. There is no window in which both resolve: the library is never published to a remote, so the ...
Right checks, SSRF/credential guards and cross-org fixes across VOIP
Findings 2-6 from the phone-system audit, fixed together because several share files. 2. HIGH β VoipInstanceController had no right check on any mutating endpo...
Verify RingCentral webhooks before trusting them
RingCentral's inbound call/SMS webhooks were processed with zero verification: WebhookController routed telephony/message-store events straight into ***********...
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...
Accept OCI image indexes when resolving the built digest [skip ci]
The images are pushed as OCI image indexes, so asking the registry for a single image manifest only answered 404, the digest came back empty and the check faile...
Restart when a same-commit rebuild leaves pods on the old digest [skip ci]
The rollout step tried to detect a same-commit rebuild by comparing the Deployment's image reference before and after `set image`. "Apply manifests" has already...
Stop telling people to add the text provider they already added
Reported from a real setup, and the report was right. An organization running FreePBX added Telnyx as a text provider, opened the SMS window, and was shown Free...
Tell a member the number is missing, not that their PBX cannot text
Reported from a real setup: an organization added Telnyx as a text provider, opened the SMS window, and was told "This phone server is a FreePBX PBX, which carr...
A frozen CHECK blocked every Telnyx AND JustCall provider from being created
Adding a Telnyx text provider 500'd. The log named it plainly and the screen said nothing useful: constraint **************** Failing row contains (..., 6)...
Ask whether THIS NUMBER can text, not whether the org can
SmsGateway grew a number-aware availability() when routing moved onto the number, and then nothing called it with a number β both SmsController call sites used ...
The "you cannot text" message stopped one step short of the fix
FreePBX and Teams told a member to add an SMS provider under Phone β Providers. That was complete advice until numbers gained their own text route; now adding a...
Only the carrier that owns a webhook URL may verify its posts
The phone-server inbound path added in the previous commit verified against whatever provider carried the number. That is a forgery surface, and not hypothetica...
A Telnyx phone server could send texts and never receive one
Telnyx is both a phone server and a carrier, and a Telnyx messaging profile has exactly one webhook URL. So an organization that added Telnyx as a PHONE SERVER ...
Populate a new number before persisting it, not after
save() built an empty OrgPhoneNumber, persisted it, and then filled in E164 and PHONE_CANON β both NOT NULL. It works today because the UUID generator needs no ...
One send contract across all five providers, and stop dropping inbound texts
The SMS abstraction layer had five providers disagreeing about how to fail and an inbound path that discarded real customer messages in silence. Sending - Se...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
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...
Stop a bad service-user JWT from disabling every member's softphone
Minting from a member's own JWT called configFactory.require(inst), which insists the phone server's SERVICE-USER JWT is present and well-formed. That credentia...
Bound the sign-in failure message carried back in the redirect
The RingCentral callback puts the server's own sentence in the query string so the member's tab can say what actually went wrong β nearly always an unregistered...
Revoke a reassigned member's RingCentral sign-in, don't just forget it
Offboarding deleted the member's credential row when they were moved off a phone server. That was the whole job while the credential could only be a JWT β Kamo ...
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.
