Release notes — Version 1.9
What changed in each version 1.9 release, newest first, as published with the release.
v1.9.11
Released 2026-09-06
- Authorization is now a capability layer: 72 named capabilities, resolved per request, replacing the empty rights scaffolding that granted admin, partner and user everything unconditionally.
- Behaviour for the six existing roles is unchanged - every grant was derived mechanically from the previous checks, and a new build gate proves the two paths agree.
- A blocked or deleted account is now signed out immediately instead of keeping its session until the token expires.
- Support access: every installation gets its own random support password, visible and switchable under Settings > Support access, with every support login in the action log.
- Deleting the support account no longer brings it back with the same password on the next restart.
- An SSH support key is now installed from a central source, and can be replaced or revoked from there.
- Devices now show the public address Asterisk observed, next to the address the phone reports.
- Service accounts no longer consume a licensed user seat.
- Bulk deletion of recordings now follows the same rule as the single delete button next to it.
- Three tenant-scope helpers no longer fall through to the operator scope for an unknown account type.
v1.9.10
Released 2026-09-06
- Payments can now carry a receipt. Opening a row in the payment list shows an upload button and the receipts already attached, with a small preview for images and PDFs. Customers see the receipts for their own payments in the portal, read only.
- Only JPEG, PNG, GIF, WebP and PDF are accepted, at most 10 MB and five files per payment. The type is checked from the content of the file, not from its name - a renamed program is refused.
- Who may see a receipt follows the payment itself: staff see what they may see of the payment, a customer sees only their own. The check sits in the download route as well, not only in the interface.
- Receipts are stored outside the application directory, so they survive an update, and they are removed together with the payment they belong to.
- This release also contains everything from v1.9.9.2: the inbound assignment for two provider accounts on the same carrier address, and the voicemail PIN setting.
v1.9.9.2
Released 2026-09-06
- Incoming calls over two provider accounts that sit on the same carrier address can now be assigned to the correct account. Until now both accounts matched on exactly the same criteria and it was undefined which one an incoming call landed on. Routing and billing were never affected - both follow the dialled number - but the codecs, the language and the provider shown for a live call could come from the wrong account. Since v1.4.2 every further account on a shared address already gets its own exclusive port for outgoing calls; that same port is now also used to recognise incoming ones. Measured on a test system: a call to the exclusive port reaches the right account, and everything else behaves exactly as before.
- The server setting that enables this is applied during the update and takes effect with the restart the update performs. On a system with only one account per carrier address nothing changes at all.
- Voicemail: a PIN changed from a telephone is now stored in the voicemail spool instead of in the configuration file. That file is generated by Voiplix and cannot be written by Asterisk, so such a change would have failed. No system has ever run into this - the setting removes the trap before the first user tries.
v1.9.9.1
Released 2026-09-06
- Security fix, and it predates v1.9.9: a semicolon followed by two dashes in a device or provider field - a caller ID name is enough - opened an Asterisk block comment and silently dropped every endpoint after it from the configuration. Measured on a test system: seven endpoints became two while the reload still reported success. Resellers and partners can reach these fields. Such input is now neutralised in the configuration generator and refused before the file is written.
- Fixed in v1.9.9: two administrators saving at the same moment could both write the configuration file at once. The lock mistook the second, unrelated request for a nested call of the first and let it through unprotected.
- Fixed in v1.9.9: after a rejected change the automatic rollback could restore the wrong version, because it used the newest backup instead of the one taken by that very save - and it also made a backup of the broken state.
- Fixed in v1.9.9: an unrelated Asterisk error logged in the same moment could roll back a perfectly good configuration. Log lines are now matched against the file and the objects that were actually written.
- Fixed in v1.9.9: the check ran before Asterisk had finished writing its log, so a failed load could be reported as success.
- Fixed in v1.9.9: if both the change and the rollback failed, the interface said nothing had been changed on Asterisk although the rejected block was live.
- Fixed: the device list is read in a fixed order now, so an unchanged configuration is no longer rewritten and reloaded just because the database returned the rows in a different order.
v1.9.9
Released 2026-09-06
- Devices and providers: an expert field for extra PJSIP endpoint options, on the device and provider detail pages, for administrators only. Two confirmations before anything is written, a preview of the effective block, and a button to go back to the generated one. Only a reviewed list of options is accepted - everything the system sets itself (routing, billing, credentials, codecs, caller ID) is refused, and every option on the list was verified against a running Asterisk.
- If Asterisk refuses the changed block, the previous configuration is now restored automatically and the extra lines are switched off until you correct them. This closes a blind spot: until now a reload could not report a failure at all. The Asterisk command line reports success even for an invented command, and when Asterisk cannot load a changed object it silently keeps the old one - the endpoint count and the reload both look healthy while the change never took effect.
- All five generated Asterisk configuration files - devices, providers, dial plan, queues and voicemail - are now written without ever emptying the file, under a lock that also holds against the background service, and with three generations of backups. Before this, saving truncated the file first: a reload or a restart that hit that moment saw an empty or half-written file. The configuration is also checked for structural errors before it is written instead of afterwards.
- Fixed a security hole that predates this release: device and provider fields such as host, IP address, language, from-user, from-domain, outbound proxy, music on hold, caller ID name and the codec list were written into the Asterisk configuration unchecked. A line break in any of them could inject arbitrary PJSIP objects - including one that accepts calls from any address - and resellers and partners could reach these fields. The check now sits in the configuration generator, so it also covers the XML API and the CSV import, which write past the forms.
- Fixed: the call monitor could report "no active calls" instead of an error when Asterisk did not answer in time, and it could mix unrelated live call events into its answer on a busy system.
- Fixed: the database deploy and migrate shortcuts never ran the intended script - they collided with built-in package manager commands of the same name.
v1.9.8.1
Released 2026-09-06
- License: a license server that answers "fingerprint mismatch" for this installation now blocks it immediately - calls, logins and provisioning - the same way as "revoked". Until now such an installation, typically the old server after a hardware move, kept running on its signed license until the expiry date. A later confirmed check clears the block; the way back is "reset" plus re-activation by the licensor.
- License: creating users and devices and importing user data now work while the license server cannot be reached, as long as the signed license has not expired. An expired, revoked, rejected or missing license blocks them immediately, as before - the expiry date is checked locally from the signed token on every request. Only the setup wizard still requires one confirmed online check.
v1.9.8
Released 2026-09-06
- License: the operator portal no longer locks out resellers, partners and customers while the license server cannot be reached. Since v1.9.4 calls already continue on the signed license until its expiry date; now logins and running sessions do the same. Only an expired, revoked or missing license still blocks - that decision is made locally from the signed token or by an explicit answer of a reachable license server.
- License: the status now says what actually happened - "license server not reached for X h", "server reached but answered pending / fingerprint mismatch", or "no contact attempt - is the background service running?" - together with the date until which the signed license stays in force. Before, every case read as "not reachable" and the banner said "SYSTEM NOT LICENSED" although calls were running. The license page shows the last contact attempt with its result, and an nginx error page in front of the license server now counts as "not reachable" instead of "the server answered error".
- License: the public-key override through the environment variable VOIPLIX_LICENSE_PUBLIC_KEY has been removed, and the offline grace is now bound to the signed token: a last-check timestamp edited into the future can no longer extend the 24-hour grace.
- License: each installation now reports its version to the license server with the hourly check; the license server records version and last contact per customer.
- License: while the license is not confirmed online, creating users or devices and importing user data stay paused as before - but the message now says exactly that. It used to claim "system is not licensed" and point to a page that resellers cannot open. All new license messages are available in all ten languages.
- Fixed: the license page showed its status line without the date ("System licensed until" and nothing after it) and the device/user limit messages without their numbers - sixteen status messages were missing from the browser dictionary.
- Fixed: the login page showed the raw text SYSTEM_NOT_LICENSED_contact_admin, in every language, when a non-admin login was refused because of the license.
v1.9.7
Released 2026-09-06
- Number pools: creating a pool now asks everything that editing asks. Valid for provider and the fallback pool could not be set while creating a pool at all - you had to create it, go back to the list and open it again. One form, one Save button.
- Number pools: the edit page now lists every place a pool is attached - devices, provider validity, fallback chains, DID blacklists, user and provider lists - and every entry is clickable.
- Number pools: deleting a pool that is still in use is refused and names what blocks it. Before, a delete left links behind that the call path kept reading; two such leftovers were found on a live system.
- Number pools: fixed a bug where saving a pool silently reset its fallback pool to none. The fallback chain is read on every call.
- Number pools: the selection method dropdown showed raw key names such as Random_default in every language.
- Number pools: a refused deletion showed the raw error key instead of a readable sentence.
- Number pool numbers: new CSV export. A file it produces can be imported again unchanged.
- Number pool numbers: the import now shows a preview and a per row error report before anything is written. It checked nothing before - abc was stored as a phone number, and a header line became one too. Wildcard entries stay valid.
- Number pool numbers: an import of more than about 32000 rows failed with a raw database error. Rows are now written in blocks, and above 20000 rows the import says so.
- DIDs: a single DID can be set as the outgoing CallerID of its device with one button. It also clears the CID pools of that device - without that, the pool rotation overwrote the number on the very next call.
- DIDs: bulk management can move DIDs into a number pool, adding to it or replacing its content, either from a typed number range or from the filter currently set on the DID list. A preview comes first, and numbers belonging to another tenant are refused.
- DIDs: the DID list has page numbers. It used to render every matching row at once - 821 rows on one system. The CSV export still contains the whole filtered set.
- DIDs: the CSV export had one translated column name out of ten, so the same export carried different column names depending on the language of the operator.
- Security: a reseller or partner could set a number pool of another tenant as the source or destination list of a customer. Both of those columns are read on every call.
- Housekeeping: this update removes number pool links that point at pools which no longer exist. Device to pool assignments are deliberately left untouched.
v1.9.6.2
Released 2026-09-05
- Mail outbox: every outgoing email is now visible under Emails > Mail outbox, with category, sender, recipient, subject and status. Failed sends are included and marked in red - that is usually why you open this page.
- Emails that previously left no trace at all are now recorded too: SMTP test messages, password-reset mails, alert mails, invoice mails, the setup test mail and the built-in voicemail text.
- A failed send now records the sender address as well. It used to be missing in exactly the cases that fail most often - sending switched off, or SMTP not configured.
- A template that has been deleted no longer fails silently: the attempt is recorded instead of disappearing without a trace.
- Voicemail entries in the mail outbox are removed after 90 days by the daily job. All other categories are kept.
- The send counter on the Emails page no longer counts invoices as template sends.
- Balances are now booked atomically everywhere. A payment booked while a call was being rated could previously be overwritten by the call and disappear from the balance without any error, log line or alert. Measured before the fix: every single concurrent payment was lost.
- The blocking decision after a call is now taken on the balance the deduction actually produced, so a customer who tops up mid-call is no longer blocked.
- The balance field in the user edit form no longer writes the balance and is disabled when editing. It submitted an absolute value the browser was given when the page opened, which silently reverted every call rated in the meantime. Use the Add to balance action instead.
v1.9.6.1
Released 2026-09-05
- Recording and voicemail players can be scrubbed again: clicking anywhere on the progress bar now jumps there. The server handed out the audio file only in one piece - the voicemail route even declared "no seeking" outright - so the browser had nothing to jump into. Both now support partial delivery.
- Customer portal: a customer now sees the balance before and after a manual payment, expandable in their own payment list, with the same breakdown the operator sees. It is their own balance, and it was the one thing the page did not tell them. The operator's editing and deleting tools stay out of the portal.
- The login logo is noticeably bigger - 200 pixels instead of 64 - and is no longer capped by a fixed width, so wide logos really do get larger instead of only taller on paper.
v1.9.6
Released 2026-09-05
- Call forwarding is reachable again: the device Callflow tab offered "Forward", but saving it failed with "Invalid action" - the feature announced in v1.9.5.3 could not be switched on at all.
- A forwarding target must now belong to the same user as the device that forwards, and a caller ID taken from a DID must belong to that device. Until now the server accepted any device and any number, including another customer's - only the drop-down was filtered.
- Saving a forwarding target or a ring time now reaches the phone system at once. Both used to sit in the database until an unrelated save happened to rebuild the dial plan.
- Moving a device to another user no longer leaves behind a forwarding that rings a phone of the previous owner, and it rebuilds the dial plan.
- Active calls: new Direction column - inbound, outbound, internal - with the same icons and wording as the call list, sortable.
- Recordings: Direction, Device and Duration columns added; the always-empty "To user" column removed; the player is now a quarter of the table width. Same wider player in the customer portal and in the voicemail list.
- DIDs: the Owner filter now really filters. Any text used to return every number that was not free, which looked like a result. Owner and Device are drop-downs, and the CSV export uses exactly the filters shown on screen - a device-filtered screen used to export more rows than it displayed.
- Themes: red and blue set only 5 of 19 colours and inherited a plain white surface. All themes now carry a complete set, secondary text has better contrast everywhere, and there are two new themes, Graphite and Teal.
- The white flash while a page loads is gone. The theme is now delivered by the server, and a collapsed sidebar arrives collapsed instead of snapping shut after loading.
- Bigger logo in the sidebar and on the login page. The login card no longer turns white on the dark login page when a light theme is selected.
- Dashboard refresh rate is now selectable, per user, with a house default under Settings, General. Nothing changes until someone picks a value.
- Payments: the balance before and after a manual payment is stored with the payment and can be opened in the list. Older payments show nothing there, because the figures were never recorded.
- The total recording size shown next to the list now covers the same users as the list and ignores deleted recordings. For accountants and partners the figure was simply wrong.
- Corrected a help text that was untrue: the Active-calls refresh interval never applied to the Active calls page.
v1.9.5.4
Released 2026-09-05
- The recordings quota was set to 100 bytes on every account by default — a value inherited from the old system, where the same field was counted in megabytes. Every account exceeded it with its first recording, so a warning email went out every day saying the limit was 0.0 MB. Accounts that never had the value changed are set to 0, which means no limit.
- The quota field now says what it is: a warning threshold. It has never stopped a recording and still does not — nothing but the warning email reads it.
v1.9.5.3
Released 2026-09-05
- Voicemail greetings can now be set from the web interface. Open a device, go to the Voicemail tab, and upload a recording for “Temporary”, “Unavailable”, “Busy” or the spoken mailbox name. Any common audio file works — the browser converts it to the format the phone system needs.
- Call forwarding now actually forwards. On a device’s Callflow tab, “No answer”, “Busy” and “Error” can be sent to another extension or to an external number, with all five CallerID choices. Until now the option could be saved but was never carried out.
- An external forward is billed to the owner of the forwarding device, not to the caller — the call is routed through the normal outbound path with that device’s account.
- The time in the voicemail notification email was shown in UTC and therefore did not match the time shown in the web interface. It is now the local time of the server, with the time zone stated.
- Removed 34 German words that were still hard-coded in the English interface — among them the device tabs, the provider form, the currency and music-on-hold pages, the SMTP settings, and the paid/sent columns of the invoice exports.
v1.9.5.2
Released 2026-09-05
- Hardening in the voicemail greeting handling: a truncated or partially transferred audio file was accepted and stored. Both checks now verify that the announced audio is actually present. Note that greetings still have no screen in the interface - they can only be placed on the server directly.
- The release acceptance tool no longer reports a pass when it could not sign in. It now verifies the session, states how many pages really answered, and lists the ones that did not.
v1.9.5.1
Released 2026-09-05
- Voicemail messages are now visible in the web interface: open a device and switch to the Voicemail tab to play, download or delete a message.
- A new voicemail is sent by email to the address stored on the mailbox, with the recording attached, and is then moved to the Old folder.
- Storage is capped. When a folder holds 100 messages the five oldest are deleted permanently, so callers can always leave a new one.
- The voicemail PIN can now be changed from the web interface, on the device's Voicemail tab.
- Asterisk no longer sends voicemail email itself. The application is the only sender, so recipients no longer receive two messages and the text follows the configured language.
- voicemail.conf is now aligned on every installation: message limit, maximum and minimum recording length, and what happens to a message once it has been heard.
- Security: the root helper now runs a root-owned copy of the setup script instead of a file the application can write.
v1.9.5
Released 2026-09-05
- Voicemail release. Voicemail was only half-built: it worked on one of the five ways a device can be created, retrieval never worked at all, and the Callflow tab wrote to a table nothing read. This release makes all of it real and fixes the telephony defects found along the way.
- Voicemail retrieval (*97) never reached a mailbox on any phone whose SIP name differs from its extension - which is nearly every phone. It looked up the mailbox from the caller ID the phone itself sends, while mailboxes are named after the extension, so retrieval reliably failed. The mailbox is now pinned to the phone by the server and can no longer be faked by the phone.
- Dialling *97 from a phone that has no mailbox used to drop the caller into Asterisk's open "enter a mailbox number" prompt. Because every mailbox is created with PIN 0, anyone could type a colleague's extension there and listen to - and delete - their messages. Such a call now hears a short announcement and is ended.
- Only devices created through the web form got a mailbox. Devices created through the XML API, the bulk create page, the CSV import or a device reassignment got none, while the dial plan still sent callers to a mailbox Asterisk did not know: nothing was recorded and the caller was simply cut off on no answer and on busy. All five paths now create the mailbox.
- Bulk create ignored the device defaults completely. Bulk-created phones differed from form-created ones in NAT, qualify, language, video, call recording and voicemail. They now get the same defaults - please check /settings/default-device before your next bulk run, because call recording is part of it.
- Deleting a device or a user left its mailbox row behind. Those orphans stayed in the Asterisk voicemail configuration, and where an orphan shared a number with a live phone, one of the two definitions was discarded: a mailbox could end up running under the name and PIN of a device that had already been deleted. Deletion now removes the mailbox, and this release cleans up the orphans that already exist.
- The Callflow tab on a device wrote to a table that nothing ever read. Setting "No answer to Hangup" reported success and changed nothing at all. "Voicemail" and "Hangup" now really govern the call. "Forward" and "Fax detect" are not implemented and are no longer offered, instead of quietly doing nothing.
- The message waiting lamp could be switched on but was never sent to the phone, because no mailbox was ever written into the phone's SIP configuration. It works now. It stays off unless you switch it on.
- The CSV device import only checked the user name, so it could create a second device on an extension that was already in use. As the voicemail store is named after the extension alone, the imported device landed in the existing owner's messages and greeting. Such rows are now rejected.
- A device reassignment left a hidden copy behind that carried the same extension as the live device, and both were written into the dial plan and the SIP configuration. Which of the two rang was undefined. The leftover is now excluded from both.
- A DID routed to a voicemail destination addressed Asterisk's own sample context instead of ours. The caller would have heard an error and the message would have been lost.
- The one-time Asterisk resynchronisation that runs after an update compared against a version number that lagged one release behind. On the test system that would have frozen after the next update, and no later release would have reached Asterisk again. It now reads the installed version.
- Opening the device defaults page and pressing Save without changing anything would have switched voicemail off for every device created afterwards, because the tick box was drawn empty while the effective default was on.
- A reseller never inherited the operator's voicemail, transport and language defaults, because provisioning copied a setting key that nothing reads.
- The rule that a fax detection device must not be placed in a ring group never took effect: it looked for a value the interface cannot write.
- Device names and extensions are now checked before they are written into the Asterisk configuration files. A name containing a line break could previously have added arbitrary configuration to a file that is reloaded immediately.
v1.9.4
Released 2026-09-05
- Database and search release. It adds the indexes the call table never had, makes the number search find a number however it was written, and repairs a caller-ID cooldown that never actually released anything. This is the first release that changes the database structure, so a database dump is taken before it is applied.
- The From and To search on the call list now finds a number by its last digits. Typing 791234567 also finds 0791234567 and 0041791234567, so you no longer have to guess the spelling the carrier delivered. Six digits or more search by ending; shorter entries still search by beginning, because two or three digits at the end would match almost every call. The CSV export uses exactly the same filter as the list on screen.
- The call table had no index on the call id, the destination or the source. Every CDR the system wrote searched the whole table, and every search on the call list read it end to end. On a busy system that was more than 1.7 million full table scans and over 200 billion rows read in a few days. Those lookups are now index based and effectively free.
- Fixed: releasing a caller ID from cooldown had no effect. The 24 hour rejection counter kept counting the rejections from before the cooldown, so the number went straight back into cooldown on its very next call, and the cooldown length you set never meant what the screen said it meant. Every release, automatic or by hand, now starts a fresh counting window, so a released number has to earn its rejections again.
- Caller IDs marked as rejected often or overused now recover by themselves. Until now nothing ever cleared those two marks, so a number that was flagged once stayed flagged until someone noticed. They are re-checked every five minutes against the pool limits and released as soon as they are back within them.
- Calls no longer stop when our license server cannot be reached. Until now a system that had not been able to check in for 24 hours refused new calls, which meant an outage on our side became an outage on yours. Your system now keeps making calls on its signed licence until the licence itself expires, and not a day longer. Creating new users and new devices still requires a verified licence, and a licence that has been revoked or has expired still blocks calls immediately.
- Number pools: a number that already sits in a pool belonging to another owner can no longer be added or imported. Importing it would have let one reseller affect the reputation and cooldown of another reseller's numbers, because reputation is held per number. The import now reports these separately from ordinary duplicates. Numbers may still appear in several pools of the same owner.
v1.9.3.2
Released 2026-09-05
- Security release, final part of the authorization work that started with v1.9.3. It closes the remaining holes and, more importantly, adds a guard so the same mistake cannot come back unnoticed.
- New build gate: every server action that takes an id from the browser must show that it checks that id against the caller's tenant. The check runs on every release and fails the build on any new unguarded action. Legitimate exceptions are listed with a written reason.
- Creating or editing a user could carry a tariff or routing (LCR) belonging to another tenant. The selection lists were already limited, but the save path was not - so the limit only existed on screen. Both now agree.
- A provider could be given the announcement sound file of another tenant, and the DID form offered the sound files of every tenant in its dropdown.
- A provider failover rule could send a failed call to any extension in the system, including another tenant's, because only the number format was checked and not who owns it. Failed calls of one tenant could therefore ring at another tenant's customer.
- IVR actions accepted any field the caller sent, which allowed the action type to be changed behind the back of the new checks and made a jump into another tenant's IVR possible. Only the intended fields are accepted now.
- The statement of account, the action log, the IP finder and the subscription list could be pointed at another tenant by editing the URL. All of them now narrow the tenant scope instead of letting a filter replace it.
- Location rules created over the XML API accepted routing, tariff, DID and device references from other tenants; the web form had already been corrected in the previous release.
- When a reseller was created, the mail server login of the operator was copied into the new reseller's settings. New resellers now start without inherited mail credentials.
- Reseller, partner and accountant permissions can finally be tested: the development system now has real accounts for those roles, so these gates are verified by running them instead of by reading the code.
v1.9.3.1
Released 2026-09-04
- Security release, second part. v1.9.3 closed the authorization holes that any signed-in customer could reach; this release closes the remaining ones, plus the ones a further sweep of the same pattern turned up.
- Reseller and partner accounts could reach across tenant boundaries in a long list of places: PBX queues and ring groups, IVR sound files, device rules, localization, cron actions, invoices, payment settings, SMS routing, number pools, e-mail templates and the data import. All of these now verify ownership before they read or write.
- Creating a user accepted the account type from the browser, so a reseller could create an administrator account for themselves. The account type is now checked against a whitelist, and only an administrator can create administrators.
- A device could be pointed at another tenant's routing (LCR), CallerID pools and CallerID entries. Because the device routing overrides the customer routing, outbound calls would have been carried by a foreign carrier account and could have gone out with a foreign phone number. All of these references are now verified, and editing a device again requires a staff role.
- The rate detail page showed every signed-in user the purchase and selling prices behind any rate, simply by walking the URL. It now requires ownership of the tariff, like the rate list above it.
- The IP finder returned every device and every provider of the whole platform to any signed-in user. It is now limited to staff and to the caller's own customers.
- External DIDs accepted a PBX pool belonging to someone else. That wrote dial plan lines into a foreign Asterisk context and, on a later change, deleted the victim's own lines along with them. The pool is now verified.
- The subscriptions list let a filter replace the tenant scope instead of narrowing it, so a reseller could read another tenant's subscriptions by changing the URL. The same pattern was fixed in the action log, which additionally showed partner accounts the audit trail of every tenant.
- Queue and ring group previews showed the dial plan lines of foreign PBX pools, because they matched only on the extension and ignored the context.
- Fixed alongside: the action log answered with a server error when opened through the user name link in the user list, and the same error could be triggered through three other filter fields.
v1.9.3
Released 2026-09-04
- Security release. Every action that acts on an ID supplied by the browser now checks on the server that the caller is allowed to touch that record. A hidden button was never protection - the action behind it could always be called directly.
- Login-as accepted the target role from the browser instead of re-checking it, so a signed-in customer account could turn itself into an administrator. The permission check now runs again on the server for every switch, and only the target ID is taken from the request.
- Devices: the SIP username and password of another customer's device could be read on the edit page and overwritten through the save action - a direct toll-fraud path. Creating, editing, deleting and hiding devices, and the device list itself, are now bound to the caller's own customers.
- Users: balance, credit, limits and address of any account could be read, and adding balance, blocking and hiding were not bound to ownership. An accountant can no longer block or hide the administrator account.
- Tariffs: rates, margins and the rate PDF of any tariff were readable by every signed-in user, and opening another tariff's user-rates page silently created zero-price rate rows inside it. Tariff pages, rate lists and the day settings now require tariff ownership.
- Provider balances were listed using a caller identity that the browser supplied. It is now derived on the server.
- Reseller groups, simple user groups, accountant groups, custom rates, device groups, DIDs, CID pools, number pools, PBX functions, BLF groups and recordings now all verify ownership before reading or writing.
- XML API: the callback action could start a call on any device in the system, the balance lookup answered without requiring the device secret, and a failed login stored the submitted password in clear text in the audit table. All three are closed.
- The WebRTC configuration endpoint no longer hands a device password to anyone outside the device owner.
- Forgot password no longer overwrites the account password on request. A time-limited, single-use link is e-mailed instead, the answer is the same whether or not the address exists, and repeated requests are rate-limited. The forgot-password page also had a German browser tab title on an otherwise English product; it now follows the selected language.
- Update backups were labelled with the version being installed instead of the version they actually contain, so a rollback reported one version too high. The backup now carries the version it holds.
v1.9.2
Released 2026-09-02
- The CID pools page of a device now shows what the rotation is actually doing. Three tiles above the list: which pool is in use right now and how often it has been used today, how full that pool is and the threshold it would switch at, and how long until the next scheduled switch. The active pool is also highlighted in the list itself, so you can see at a glance where the calls are coming from.
- Please note what the countdown means: the switch is decided when the next call arrives, not by a timer running in the background. If the device is idle the countdown reaches zero and stays there, and the tile then reads 'On the next call' instead of claiming a switch that has not happened. On a quiet line that is the honest answer.
- The live figures are on the CID pools page rather than in the device form on purpose: that is where the pools are listed, the fill level is already a column there, and a ticking countdown next to unsaved form fields would be more confusing than useful. The device form points to it.
- The release build now refuses to publish if any shell script in the package has Windows line endings. A stray carriage return in a script does not produce a helpful error - bash fails with something like 'command not found' or 'bad interpreter' - and the scripts in question are the ones that run on your server during an update. This guard existed for install.sh only; it now covers all of them.
v1.9.1
Released 2026-09-02
- New hangup cause 900 'Call skipped - no CallerID left in the pools'. Until now a call that was skipped because every number in the device pools was in cooldown, quarantine, retired or blocked was recorded as 204 'No suitable providers found'. That was misleading, since the provider was fine and only the CallerID was missing. The new code is in the 9xx range, which is reserved for this product's own codes: it cannot collide with the standard ITU-T Q.850 codes (0-127) or with the other product-specific codes (200-286).
- Fixed: on a device CID pools page the table was capped at a narrow width, so after the state columns arrived in v1.9.0 the Action column was pushed almost out of sight. The table now uses the full page width and scrolls sideways on small screens instead of cutting the last column off.
- You can now apply a reputation action to every number of a pool at once. Next to Reset counter and Delete all there is a new selector offering the same actions you already had per row - release, cooldown, quarantine, decommission, reset counter - applied to all numbers in the pool. It asks for confirmation and names the number of entries first, and it writes a single line to the action log rather than one per number.
v1.9.0
Released 2026-09-01
- Caller ID pools can now rotate by themselves. A device set to the new mode 'Random number pool from CID pools' picks the POOL from the ones linked under CID pools - not a fixed one - and moves on as soon as either of two conditions is met, whichever comes first: a time interval you choose (30 min up to 8 h), or a pool dropping below a percentage of usable numbers that you set per pool.
- Why this exists: with a fixed priority order the first pool carries the entire load until it is empty. On a busy dialer we measured 6,677 rejects on the pool at priority 1 against 500-1,000 on each of the twelve behind it, and every number in the first pool went into cooldown while eleven pools sat unused next to it. The rotation spreads the wear instead.
- The pool is chosen the same way numbers already are: lowest use counter first, ties broken at random, with an optional deviation. Each pool counts one use per turn - not per call - and the counters reset daily at 23:59.
- A threshold only ever triggers a switch. It never blocks a call: if every pool is below its threshold, one is still chosen and the existing fall-through to the next pool stays in place. This is deliberate - a rule meant to protect your numbers must not become the reason a call fails.
- You can now see the state of every pool without opening it. The pool list and the CID pools page of a device show usable, in cooldown, blocked, fill level and the use counter, and a banner appears when pools are running low. Watch the fill level rather than the blocked count: the blocked count stays near zero almost to the end and then collapses, while the fill level rises steadily and gives you hours of warning.
- The action log now records what changed, not just that something changed. Adding or removing a pool on a device, changing its priority and changing its switch threshold are written with the old and the new value.
- Nothing changes for existing installations until you switch a device to the new mode: the defaults keep the current behaviour, and priority keeps working exactly as before in the existing pool mode. In the new mode priority no longer applies - the page says so and disables the field rather than offering a setting that does nothing.