Skip to content

Airpane CHANGELOG

Hier werden sämtliche Änderungen an Airpane Controlpanel dokumentiert. Wir bemühen uns, dieses Changelog regelmässig zu aktualisieren, um alle Änderungen festzuhalten.

Hinweis

Bitte beachte, dass wir Continuous Deployment (CD) anstreben. Das bedeutet, dass Änderungen an Airpane Controlpanel in der Regel sofort live gehen, mehrmals täglich. Daher kann es sein, dass du Änderungen siehst, die noch nicht in diesem CHANGELOG dokumentiert sind resp. die unten stehenden Releases nur als «Milestones» zu verstehen sind.

English version only

Das CHANGELOG ist nur in Englisch verfügbar, da wir unser gesamtes Issue-Tracking und interne Dokumentationen nur in Englisch führen.

v3.8 (2026-05-15) – Unreleased

v3.7 (2026-03-09)

  • Gracefully handle Redis connection failures: Only report first RedisException during a 2min grace period in #1112
  • [Bug] Fix SSH profile deployment on hosting where home has not yet been set up (SSH not yet activated) in #1111
  • Fix HasMany::sync() macro to no longer clone the relation instance which caused missing FK constraint issues in #1110
  • Implement MaintDomainRunDnsCheck command to run DNS checks domains with external NS / generate reports in #1108
  • Improve SieveConsistency command to mark Mailaccounts with inconsistent Sieve scripts as dirty in a single update in #1107
  • Remove saloonphp/laravel-http-sender dependency, replacing HttpSender by GuzzleSender for Saloon integrations in #1105
  • Run scheduled Domain Contact Verification Status check ( DomregMonitorContactVerification command) to prevent suspension for domain owners without verified email in #1104
  • [Security] Protect Orderform API and User Registration by RejectDirtyInput middleware, rejecting any XSS input attempts in #1102
  • Allow longer customer company names of up to 50 chars in #1101
  • Extend DKIM key management: Allow creation of DKIM keypairs / TXT records for infra subdomains (Dedicated webservers) in #1100
  • [Feature] Implement overquota health check for system mailaccounts, SystemMailaccountsQuotaCheck in #1099
  • Streamline composer.json / add more scripts from laravel/vue-starter-kit in #1098
  • Improve Cronjob frequency input field: Normalize whitespace to single spaces / prevent Invalid cron expression frontend validation error in #1096
  • Make health check notifications less noisy: Only notify on failed checks, ignore warnings, implement HasFailedAfter trait in #1095
  • Introduce Radiance: Generate Deterministic Mesh Gradient Avatars / Replacing UI Avatars API generated boring avatars with initials in #1093
  • Gracefully handle RequestException as HTTP 404 on Access Stats, when customer tampers with the URL (non-existing GoAccess report) in #1092
  • Improve collecting billable Customers by smarter readyForBilling() scope / also check for open statements due date if customer only has renewal statements in #1091
  • Improve GitLab CD deployment, ensuring frontend build assets are always accessible by Apache in #1090
  • [Bug] GitLab CD: Polluted git repo due to mismatching Node/NPM versions breaks deployment in #1089
  • [Bug] Tooltips not shown on disabled ActionLink in #1080
  • Fix PHP 8.5 Deprecations in vendor packages in #1031

v3.6 (2026-01-22)

  • Bump Laravel v12.48.1, Inertia v2.3.11, Vue v3.5.27, Tailwind v4.1.18, Vite v7.3.1 in #1087
  • Improve Subscription Edit / Cancellation of addon subscriptions by custom end date in #1086
  • [Feature] Extend Customer/Hosting Permission Card management to regular admins in #1084
  • GitLab CI: Upgrade testing/deployment environment to Debian Trixie (13) in #1083
  • Replace spatie/laravel-horizon-watcher horizon:watch by laravel/horizon v5.43's new horizon:listen (local dev) in #1082
  • [Feature] Allow custom MySQL Users with complex permissions (not editable) in Database user manager in #1079
  • [Bug] RenewSubscriptions command renews all child subscriptions (addons), even if they were canceled in #1078
  • [Feature] Add billDelayed scope on Customer and add it to admin filters on CustomerDashboard, Admin CustomerSearch in #1077
  • Prevent race condition on Subdomain updates/deletion (duplicate vhosts reconfiguration via Airpane-agent) in #1074
  • [Bug] Missing extra data fields on domain transfers of TLDs that require extra data in #1073
  • [Bug] Wrong HTML DOCTYPE rendering in GitLab CI on NewInvoice notification snapshot testing in #1072
  • [Bug] Exclude billing related scheduled tasks in ScheduledTasksCheck health check when billing is paused in #1071
  • [Bug] PolicydRateGuard webhook rejects legacy mailaccount usernames without sending out PolicydLimitReached notifications in #1070
  • Add Domain-MailadminPRO product: Mail-only plan for unlimited emails / 50 mailaccounts / 50GB in #1069
  • Relax domain alias to main domain propagation (admin feature) for 3rd level domains in #1068
  • Create admin MaintMigrateSplitHosting command to migrate domains and split parts of an existing to a new hosting in #1067
  • (Investigate) Replace Bexio invoice QR code cropping by QR code detection/parsing in #1065
  • [Bug] Changes on subscription end date are charged/refunded even when StatementStatus::IGNORE was set in #1064
  • Add mailaccount username to deletion confirmation modal message / allow Markdown formatting in DialogModal contents in #1062
  • Upgrade to Inertia.js v2.3.0 with built-in Precognition / ditch laravel-precognition-vue-inertia in #1061
  • Extend Laravel-Health to send recovery notification when all checks have recovered to ok status in #1060
  • Add server multiselectFilter to Hosting Dashboard and Admin Hosting Search in #1059
  • Prevent Subscription renewals for upcoming year period to get invoiced in current year in #1058
  • Add a human_status virtual stored column to bexio_invoices to make the status id human readable in #1057
  • [Bug] 2FA input field for code trims leading zeroes / replace by improved OtpInput component in #1056
  • Introduce an extra email header for high priority notifications that should be respected/reviewed by our Support Team in #1055
  • Modernize email template CSS in #1054
  • Migrate service reload commands in CI/CD to Laravel v12.41's new reload command in #1053
  • Store output of scheduled FetchDisposableEmailDomains (ashallendesign/email-utilities) command to logfile in #1052
  • Make DNS zonefile contents reactive on DNS record changes: Introduce polling while Dnszone is deploying in #1051
  • Add Order factory and run OrderConfirmationEmail notification snapshot testing in #1050
  • Allow admins to manually invoice open statements for customers even when below the open statement threshold in #1048
  • Admin action: Allow replication of canceled BexioInvoice's (Bill) positions (statements) in #1047
  • [Bug] FTP users are not undeployed from previous server when migrating Hosting to another server in #1046
  • Improve Email::strictNoDns() validation by also validating hostname in email domain part in #1045
  • [Bug] On email forwarding edit sometimes getting frontend TypeError: Cannot read properties of undefined (reading '0') in #1044
  • [Bug] Deletion of Mailinglist fails with HTTP 500 if mailinglist was already removed on Mailman3 server in #1043
  • Prevent Mailaccount password reuse on UpdateUserPassword and ResetUserPassword action, in addition to User account registration in #1042
  • [Bug] Fix GitTest random failures in GitLab CI on full parallel test run in #1041
  • Refactor Mailmap::getExtForwardings() to be more readable/fluent in #1040
  • Improve MxCheck command: Add optional domain argument, --force option in #1038
  • [Performance] Prevent filling up the default queue by the Debouncer on Mailmap bulk updates (ProcessDeployRspamdForwardings job dispatches) in #1037
  • [Bug] Email still gets locally delivered to active mailaccounts, even when transport_suspended flag is set / Improve MxCheck to also suspend/unsuspend mailaccounts in #1036
  • [Security] Enforce EmailDomainIsNot::disposable() validation rule on every email field, not just for User registration in #1035
  • [Performance] Improve performance of mailaccount overview, reducing the number of GetAllMailaccountQuotas cache hits in #1034
  • [Bug] Fix sporadic gethostbyaddr(): Address is not a valid IPv4 or IPv6 address in GitLab CI / local dev in #1033
  • [UX] Admin Billing Run: Add action button to show related invoices / Add NextRunBadge on top in #1030
  • [Feature] Add trusted status to User Administration in #1029
  • [Feature] Display total sum on Invoice overviews (Customer Bills, Admin Invoice Search / Send Invoices) using OVER() window function for aggregation in #1028
  • [Feature] Added Database Backup Restore information (timestamp / target DB of last restore) to DB Backup manager in #1027
  • [Feature] New consistency check for Hosting relations: Ensure existence of primaryFtpUser and mainSubdomain in #1026
  • [Bug] Cannot restore a db in Database Backup Manager: ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SET_ANY_DEFINER privilege(s) for this operation in #1025
  • [Feature] Pingen eBill integration with webhook for new eBill registrations in #1017

v3.5 (2025-11-14)

  • Bump Laravel v12.38.1, Inertia v2.2.16, Vue v3.5.24, Tailwind v4.1.17, Vite v7.2.2 in #1024
  • [Performance] Cache Routes and Config During Testing (available since Laravel v12.38) in #1023
  • [Feature] ReconfigureVhosts Admin Maintenance Task: Support exact timestamp to filter Hostings to be deployed in #1022
  • Enforce consistency of single primary FtpUser per Hosting on DB level / Simplify primaryFtpUser relation in #1021
  • [Bug] Fix lazy loading issue on full server VirtualHostData deployment / eager loading of primaryFtpUser in #1020
  • [Bug] Fix Hosting primaryFtpUser relation for ftp users in unexpected order (addon ftp users created before primary) in #1019
  • Add translations for OrderStatusBadge status options on hosting order in #1018
  • [Bug] Fix SslcertRemoveOrphaned command to no longer try to remove non-Letsencrypt certs in #1016
  • [Docs] Add help-docs for New Hosting Setup in #1015
  • [Security] Only allow globaladmins to change a Hosting's server for (re)deployment on webserver migration in #1014
  • [Feature] Allow PHP max_file_uploads to be tuned by customers in Hosting PHP Manager in #1013
  • [Bug] Fix too restrictive validation on dbsourcehosts in UpdateHostingSettingsRequest in #1012
  • [Feature] Extend PHP legacy support configuration (replacing php_stick_old flag): Allow multiple PHP old handlers, configurable on Hosting level in #1011
  • [Bug] DomainRunRegistrations command stops looping over Domreg updates when first returns false in #1010
  • [Refactor] Use CurrentUser attribute to inject the User in controllers wherever possible in #1009
  • Restrict daily Sender-Limit for Mailaccounts with low Zxcvbn password score in #1008
  • [Feature] Show Password Score badge for Mailaccounts, FtpUsers, DbUsers / Banner on Mailaccount Overview to warn about usage of weak passwords in #1007
  • [Bug] Fix timing issue on Mailaccount rename, where WarmupMailaccountQuotas job clashed with next mailaccount rename on bulk renames (with MaintRenameMailaccounts csv option) in #1006
  • Add username and auth guard to Sentry as additional tags in #1005
  • [Bug] Extend DomainAvailabilityStatus enum cases for (undocumented) INWX API domain.check with added progress status in #1004
  • Upgrade to Node.js v24 "Krypton" LTS / npm 11.6 in #1003
  • [Bug] DP: Primary FTP users for legacy domainMailadmin hostings were not imported on migration from airpane-zf1 in #1002
  • Extend filters/sorting on Mailaccount Overview: Filter for inactive mailaccounts, Quota range filter, sortable email in #1001
  • [Feature] Tinker: Pre-alias classes in App\Models namespace so they don't clash with others in #1000
  • [Feature] Hostings Overview for Regular Users with Subdomain/PHP-Version overview and CSV Export in #999
  • [Feature] Implement Console Command MaintPhpUpgrade for PHP major version upgrade / notification to webmasters in #998
  • [Bug] INWX API extra data validation regression: IDCARD-OR-PASSPORT-NUMBER is required along with ADMIN-IDCARD-OR-PASSPORT-NUMBER on .VN domains in #996
  • [Bug] Domain Mailadmin Hostings: 3rd-level domains are not getting added as mail domain on hosting creation in #995
  • [Bug] Fix Directory Protection not getting applied to correct subdomain (wrongly resolved from relative directory path) in #994
  • Replace Tailwind v4 deprecated classes (mainly opacity related, replacing by opacity modifiers) in #993
  • [Bug] Fix Node.js v22.21.0 regression / TypeError: server.shouldUpgradeCallback is not a function (fixed in v22.21.1) in #992
  • PHP Manager: Improve PhpVersionLayout for more than 4 different PHP versions, moving Cache Reset buttons to dropdown menu in #991
  • Upgrade to PEST 4.0 in #988
  • [Bug] DP: Shell activation for SSH access fails on SYSTEM_LOGIN_IS_USERNAME=false (system.loginIsUsername config) in #987
  • Improve performance of GetFtpTraffic request (Airpane-agent) by introducing ftpxferlog_cleanup EVENT on MySQL 8.4 db level / Improve traceability of response in #986
  • Fix ExtractQrCodeFromInvoicePdfTest image snapshot testing in CI: Missing node dependency for spatie/pixelmatch-php in #985
  • [Bug] Fix Bexio invoice QR code cropping for vertical positioning variations in #983
  • Prevent Mailaccount password reuse on new user account registration (avoiding confusion, improved security) in #982
  • [Bug] Multiselect: Fix spacing of InputError validation message in relation to Listbox component in #980
  • [Bug] DnsrecordCnameConflict validation rule does not allow to add any new DNS records if wildcard CNAME exists in #979
  • [Testing] Add ArchTest to ensure all FormRequest classes have the Request suffix in #978
  • [Bug] Fixer.io health check frequently times out / raise 3s timeout in #977
  • Simplify INWX domain contact handles configuration, no longer using different admin contacts for specific TLDs in #976
  • [Feature] Add password score and pending new password information to User Overview (Admin Area) in #975
  • [Feature] Create MaintRenameMailaccounts command to bulk rename mailaccounts / moving mailaccounts to different hosting(s) in #973
  • [Feature] Domain Contact Handles Manager: Create/Edit domain contact handles independently from assigned domain(s) in #851
  • [Bug] Fix SaloonCommon\HasDefaultCachingTest (sometimes failing on full --parallel test run) in #567

v3.4 (2025-10-06)

  • Make DomregContactConsistency more failure-proof, adding safeguards against default INWX contact handle misconfigurations in #974
  • [Bug] Newly registered domain is not charged when registrar (INWX) API reports zero cost / caused by stale DomainLog request cache in #972
  • [Bug] Fix HTTP 500 when trying to change senderlimit quota of a mailaccount which was never added to Policyd-rate-guard before in #971
  • Workaround for FEDERATED connection issues in MySQL 8.4.6: Warmup FEDERATED table connection before hitting write operations by pinging the remote table on current DB connection in #970
  • Improve Mailsync TRIGGERs by minimizing connections to FEDERATED tables (lowering potential of lost connections in MySQL 8.4) in #969
  • [Bug] Dbbackup stuck in restoring state, even though completed / raise timeout for RestoreDbBackup request in #968
  • [Bug] Fix lazy loading issues on subdomain (with masterSubdomain) updates / VirtualHosts deployment in #967
  • Improve handling of failed domain transfers with invalid auth code / Allow retry with new auth code in #966
  • [UX] Improve UpdatePhpconfigRequest validation messages for lte rules in #965
  • Order form: Block disposable email domains from our blocklist in #963
  • [Bug] Cannot edit autoresponse on deactivated mailaccount with suspended transport / Prevent vacation changes in #962
  • [Bug] Allow storing larger restorePrice in INWX domainprices (DomainPricingUpdate command) in #961
  • [Bug] Allow superadmins to change or remove explicit hosting permissions even if there is no (implicit) hosting admin in #959
  • Raise mailaccount management SSO rate limit for Roundcube logins in #957
  • Extend MaintAlignChildSubscriptions command to also align customer ID of any potential inconsistencies on child subscriptions in #956
  • [Bug] ValueError: "ES-ID" is not a valid backing value for enum DomainExtraData (.ES TLD) in #955
  • [Feature] Create MaintMailaccountRestoreHam command to restore accidentally moved emails from Spam folder to invoke Bayes ham learning in #954
  • Migrate Sentry for Vue SDK 9.x to 10.x in #953
  • [Regression] Fix symlinking of latest release on deployment via GitLab CD in #951
  • [Bug] Fix deployment of Htprofile with Htuser that still have legacy Apache-style SHA-1 password hashes in #950
  • [Regression] Fix HTTP 405 Method Not Allowed on mailaccount password reset form (on production/staging env) / Fortify routes caching problem in #949
  • [Bug] Regular User cannot edit nameservers of a Domain, even if it is correctly linked to a Domreg (registered domain) in #948
  • Add warning to nameservers edit form: Click on Update button to apply the changes in #947
  • Log validation errors to laravel.log in #946
  • Prevent RequestException (HTTP 403) reporting / airpane-agent PermissionError on dirlist in #945
  • Validate crontab command to not start with a cron expression (frequency) in #944
  • [Regression] Revert CrontabExpression validation rule to use poliander/cron for strict cron expression syntax in #943
  • [Feature] Collect Rspamd Spam/Ham-learning statistics in #941
  • [Bug] Fix BexioHelper::getLastClosedBusinessYearTs(), where last closed business year is based on ID in #940
  • [Bug] Only remove Let's Encrypt certs on Subdomain deletion / never delete system Sslcerts (e.g. for infrastructure domain) in #939
  • [Bug] Addondomain changes (domain redirect target URL) are not getting deployed to webserver in #938
  • Collect and deploy subdomain records for infrastructure domain(s) in #937
  • Prevent tampering with addon subscription creation on missing parent subscription: Improve backend-side validation on CreateSubscriptionRequest in #936
  • Improve fail-safety of DomainRunRegistrations command, stop retrying domain registrations/transfers on failures (e.g. due to rate limiting) in #935
  • [Feature] Add filter for trashed (soft-deleted) subscriptions to Customer Subscription overview in #933
  • Frontend Error: ResizeObserver loop limit exceeded in #914
  • Override Laravel-Health German translation, defaulting to en in #814
  • Migrate to ESLint 9.x / flat config eslint.config.js in #443

v3.3 (2025-07-15)

  • [Regression] Admin Maintenance Tasks: Disabling of health checks no longer possible, as Artisan command args are not correctly resolved for Process::run() in CLI in #932
  • [Bug] Potential deadlock situation on Hosting deletion due to nested transactions (HasTransactionSafety.php trait) in #930
  • [Regression] INWX RequestExceptionDTO: "The code field is required" on account.login empty response body (InwxHealthCheck) in #929
  • [Regression] INWX API may return avail: -1 for domain availability of .CLOUD / cannot be cast to bool in DomainCheckDTO in #928
  • [Feature] Formal de translation overrides for KMZ/Datenpark NewInvoice notifications in #927
  • [Bug] Cannot update a cronjob command that points to a file that is followed by a quote / loosen CrontabCommand validation rule in #926
  • [Bug] When updating a Subdomain's masterAttributes, the Apache Vhost of the affected child hosting(s) is not reconfigured in #924
  • [Bug] Fix lazy loading issue Subdomain Overview (subdomain.index) / masterSubdomain related in #923
  • Refactor CustomNotifiable from Sushi model to regular Eloquent model without database table for on-demand notifications (incl. database channel support) in #921
  • [Security] Prevent plaintext password exposure in HostingAccessinfoEmail: Only send masked copy to admin (instead of Bcc) in #920
  • [Security] Prevent plaintext password exposure in MailaccountAccessinfoEmail: Only send masked copy to admin (instead of Bcc) in #919
  • [Bug] Cannot update vacation message (Sieve autoresponse) on deactivated mailaccount in #918
  • Team Permissions help-docs: Document Hosting and Customer roles in #917
  • Only log a warning when reaching SSL cert deletion limit on SslcertFixExpiring instead of throwing ArgumentOutOfRangeException in #916
  • [Regression] Customer Domain Overview: Make the delete button clickable again with alert modal when there is still a related hosting or running subscription in #915
  • [Feature] Publish rendered CHANGELOG.md to public help-docs, making it available to all customers in #913
  • Improve scheduling of InvoiceAllCustomers quarterly full billing run using dragonmantank/cron-expression extended cron syntax in #912
  • Add customer information (customer no, description) to NewInvoice notification in #911
  • [Bug] Person name is not included on SshAgreement PDF company contact address in #910
  • [Bug] Prevent SendInvoices command from sending customer invoices with wrong template_slug (Bexio) in #909
  • Include billing email in Customer search email filter in #908
  • [Bug] Tooltips on domain TLD pricing cards are no longer shown on hover in #907
  • Prevent syncing of Bexio invoices with unknown template_slug (created with another invoice template) / Improve MaintBexioSyncContactIds command in #906
  • Improve GitLab CI deployment by copying latest target release using readlink current in #905
  • [Bug] Fix missing deactivation timestamps on inactive Mailaccounts (and other tables) in #904
  • Improve handling on Bexio API downtimes (maintenance) / Handle OAuth2 access_token refresh gracefully in #903
  • [Bug] Scheduled DomainPricingUpdate command failed / make DomainPriceRecordDTO validation more tolerant for inconsistend INWX API data on domain.getPrices in #902
  • Make mailaccounts Subscriptions (DP/KMZ Kirchenmail) up/downgradable in #901
  • Improve VerificationEmail notification to include the new email address when changed in #900
  • [Bug] Scheduled MaintBexioSync command failed on export-contacts in #899
  • [Feature] CSV Export for Mailaccounts / Email Forwardings in #898
  • [Bug] Fixer.io Rate Limit exceeded (even though totally within limits of 100 req/mo) in #897
  • Add timestamp (when migration was applied) to migrations table in #896
  • [Bug] DeactivatedMaildomainBanners not shown on mailaccount overview for maildomains that have been deactivated prior to 2025-02-27 (migration) in #895
  • Cleanup: Queue more notifications / Remove Queueable trait from notifications that don't implement ShouldQueue interface in #894
  • Improve MailaccountQuotaWarning notifications: Add alternative email contact to Cc, smarter warn frequency (increment interval by 3d after the first 3 warnings) in #893
  • [Bug] Current search/filters/per-page settings are lost on Email Forwardings overview, after editing a forwarding in #892
  • [Feature] Mailaccount Password Reset with option to generate new password and send MailaccountAccessinfoEmail to Webmaster in #891
  • [Bug] Fix lazy loading issues on SslcertIssueAll > SiteConfigurator::getMaintenanceData() (MasterAwareModel related) in #889
  • Sort custom DNS resource records in a smart order on deployment to avoid diverging zonefile contents in #888
  • Upgrade to Vite v7.0 (bump vite, @vitejs/plugin-vue, laravel-vite-plugin) in #884
  • Rewrite FolderPicker and DirectoryListingFetcher components to support dotted or numeric dirs again in #819
  • GitLab CI: Re-activate Pint tests / PHP 8.4 class instantiation / Upgrade to PHP-CS-Fixer v3.80.0 in #615

v3.2 (2025-06-25)

  • [Feature] Nameservers edit modal: Add button to reset NS to our defaults in #887
  • Admin User Manager: Improve filtering of trashed (soft-deleted) users in #886
  • Prevent DNS zone management for infrastructure domain(s) in #883
  • [Bug] OnboardMigrateViaFtpUser cannot be retried after unverified previous migration and user removal in #881
  • [Bug] BexioSyncPaidInvoices command fails on old Bills with trashed (soft-deleted) customers in #880
  • Display WelcomeInfoCard with signup instructions for guests that have never logged in (in addition to OnboardingInfoCard) in #879
  • Make StatementStatusBadge visible for all users / document statement status in help-docs in #878
  • Set User Overview as default on admin area on login / SuperadminAreaToggler in #877
  • [Bug] Fix output buffering problem on SafePhpinfo (Error: Cannot modify header information) in #876
  • Disable two factor authentication confirm button when form is processing / Improve 2FA confirmation form styling in #875
  • [Bug] Fix timezone mismatches on Customer edit form, where bill_delay gets converted to UTC in #874
  • [Feature] Improve UX on DNS Manager: Remember last RR Type in localStorage, don't stick with MX default in #872
  • [Bug] CommandPalette: Get Ctrl-K working on Linux/Firefox, overriding the built in keyboard shortcut in #871
  • [Bug] Fix Horizon restart from Admin Maintenance Tasks web (PHP-FPM) context, not executing horizon:terminate in CLI in #869
  • [Security] Obfuscate Bexio API OpenID Connect (OAuth 2.0) tokens in request/response body (onlime/laravel-http-client-global-logger v1.2.3) in #868
  • [Feature] CSV Export for Admin Customer Search in #867
  • [Feature] CSV Export for Admin Subscription Search in #866
  • Smart products sorting in Admin Subscription Search product filter, Create Addon Subscription form in #865
  • frontend: Make InfoBox light style the default, as it looks better and is already widely used in #864
  • Migrate Htdir relations (directory protection) on Subdomain swapping, in addition to configuration in #863
  • Pass CustomerTeamRole::ADMIN role to parent team if defined in #861
  • [Bug] Prevent superadmins from adding team members to personal team (already enforced for regular users) in #860
  • Also send out notification to team members on changes hosting/customer permission (UpdatedTeamPermissions notification) in #859
  • [Bug] DNS manager: Cannot update existing TXT SPF record due to DnsrecordSingleSpf rule in #858
  • Migration: Set is_master flag on all master hostings which are referenced by other hostings in #857
  • Deprecate null_or() helper in favor of Laravel's optional() helper in #856
  • [Security] Impersonation: Allow superadmins to pass Customer/Hosting permissions without knowing the impersonated user's password in #855
  • Fix lazy loading issues when assigning a Sshprofile to a Hosting (sshprofile.create) in #854
  • Add admin button to toggle domain registration (pause/resume) on PENDING domain registration/transfers in #853
  • RateLimiter for domain registration failed attempts to avoid running into INWX Grabber Defense rate limit in #852
  • [Security] Refactor superadmin access / Admin Area switching (allow toggling of Customer/Admin Area for all superadmins, even when not on Personal Team) in #850
  • Fix lazy loading issues on DomainRunRegistrations / RegisterDomain action in #848
  • [Bug] Prevent domain registration of .EU domains with non-EU contact data / add DataAwareable CountryMatchesContact validation rule in #847
  • Provide legacy Mailinglist API (from airpane-zf1) as alternative API for Mailman3 mailinglists in #846
  • Create MaintPullStorage command to pull storage/app assets from remote environment in #845
  • Implement Customer deletion for superadmins, triggering archiving of related Bexio contact / Mite customer in #844
  • Sentry: Filter frontend exceptions caused by embedded Chromium crawler (CefSharp / most commonly Microsoft Outlook Safe Links scanner) in #843
  • Add Postfinance MFTPF status with config overview to Admin API Integrations dashboard in #842
  • Implement mocking / fake response for Mite API GetAccount request in #841
  • Improve dbprefix (DP only) validation on Hosting creation form in #840
  • Allow Laravel-Health checks to be enabled/paused via Admin Maintenance Tasks ServicesCard in #839
  • Prevent Laravel Health check false-positives during deployment (health:pause for 30s to prevent HorizonCheck from alerting on restart) in #838
  • Update Bexio API integration for new Contact address data structure (street_name, house_number, address_addition) in #837
  • [Bug] Fix eager loading issues with primaryFtpUser on Admin Hosting Search, where app.system.loginIsUsername is disabled (Datenpark) in #836
  • API integrations: Make Postfinance MFTPF and Mite API better configurable (disabled at DP) in #835
  • Datenpark Branding: SVG logos, useBrandAssets() composable, Tailwind brand color styling with themes in #834
  • Domain Search/Registration: Prevent users from adding domains with www prefix in #833
  • RedirectToMailaccountLogin Fortify middlware even redirects to /mail/login when using same password on mailaccount as for user account in #832
  • [Feature] Mite Integration: Add admin button to Customer card to create new Mite customer/project in #830
  • Add --server and --username options to the MaintCreatePhpFpmPools command for limited deployment in #829
  • Customer/Hosting Permissions Card to display assigned team permissions, and allow superadmins to pass/modify permissions in #828
  • [Security] Re-deploy all PHP php.ini configs with zend.exception_ignore_args = On (now enabled by default) in #827
  • Admin Billing Run / Invoice Search: Add "Next Run" date badge to show when unsent invoices are going to be sent out automatically in #826
  • [Regression] ScheduledTasksCheck health check wrongly reports task as missed if taking too long to start in #825
  • Create a new product ProductId::SYSADMIN for correct Mite statement import mapping / Sync to Bexio in #824
  • Tune MaintUndeployHosting for big data: Raise AirpaneAgent timeout for DeleteWebhome and DropAllDatabases requests in #822
  • Improve AirpaneAgent health checks (randomly timing out after 4s) in #820
  • [Bug] Hosting badge and Domreg owner information lost when filtering/searching domain overview (SearchBuilder eager loading) in #797
  • Improve CommandPalette UX by showing hostings on top (above customers, domains) in #782
  • [Bug] ClearLoginIdOnLogout Logout listener fails on missing User in #763

v3.1 (2025-05-15)

  • Fix Carbon deprecation WARNING: Use the method diffInSecond instead to make it more explicit about what it does / floatDiffInSeconds deprecation in #818
  • [Bug] Windows users cannot upload .pub SSH pubkeys: File type 'application/vnd.ms-publisher' not allowed. in #817
  • [Bug] Prevent upload of multi-line SSH keys, potentially uploading multiple keys with \n line separators in #816
  • [Feature] Allow SSH keys of same email domain as team owner to be added to SSH profile in #815
  • [Bug] Subdomains contain annoying space separator between name and domain when copied in #813
  • [Security] Add health check to ensure absence of any Composer require-dev packages on production in #812
  • [Bug] Fix Log Viewer authorization in production (handled in global Gate::before() override) in #811
  • Add MaintUndeployHosting command for manual cleanup of hosting which was migrated to another server in #810
  • Customer Revisions: Visually highlight admin-only visible fields in modified fields diff in #808
  • [Bug] Laravel-Health ScheduledTasksCheck reports failed task multiple times in #807
  • [Bug] GitLab-generated CHANGELOG.md misses some closed issues in v3.1 milestone / Use Saloon Pagination for GitLab Issues API per_page limit of 100 in #806
  • [Bug] Avoid column break inside CustomerCrudGridCard on long address data in #805
  • Improve PHP Config Manager validation errors on interdependent values of ini directives (only show validation errors on dirty fields) in #804
  • [Regression] UpdatePhpconfigRequest: Broken validation for dotted keys since Inertia v2.0.7 (Support for nested paths in forms) in #803
  • Pretty-print Site Config JSON output (admin.hosting.site-data) in #802
  • [Bug] SslcertFixExpiring breaks Apache vhosts config when undeploying Sslcerts of multiple hostings in #801
  • Improve DomainTransfer notification for .COM/.NET/.ORG domains with long (5d) transfer time in #800
  • [Bug] UpdateDomregFromRegistrar action may access non-existing expiry date in #798
  • [Bug] Cannot set special price to zero (0.00) on subscriptions with variable price (domain registrations) in #796
  • [Regression] npm hangs since Node v22.15 / Homebrew-only issue in local dev in #795
  • [Regression] Scheduled commands failing after Composer upgrades / Laravel v12.11.0 regression in ScheduledTaskFailed in #794
  • [Bug] AppSettingsTest fails randomly on full parallel test run in #793
  • [Bug] Cannot delete domain subscription on domain in DELETE INITIATED state (after expiry) in #792
  • [Security] Prevent hammering order form processing: Delay pending orders exponentially / Add global switch to pause order processing on admin tasks in #791
  • Improve Postfinance camt.054 transaction booking: Add overpaid amount to transaction report, in addition to logged warning in #790
  • [Bug] QueryException on customer update: Column 'salutation' cannot be null in #789
  • [Bug] FolderPicker breaks when DirectoryListingFetcher tries to access directories with dots or numeric dirs in #788
  • [Bug] PreserveCrudListQueryParams middleware fails with array_intersect_key(): Argument 1 must be of type array, null given in #787
  • [Bug] Prevent main subdomain creation on limeDRIVE hosting in #786
  • Upgrade PHP default handler to PHP 8.4 in #785
  • Collect web traffic (traffic stats) for published limeDRIVE hostings in #784
  • [Bug] Empty logrotation of symlinked hostings (causing empty access stats, affected: web180) in #783
  • [Feature] Orderform webhook for Onlime.ch order form / Implement direct Hosting order processing in #781
  • [Feature] Add WebDAV / Web Publish support for limeDRIVE hostings in #780
  • [Bug] Hide domain dropdown on new hosting modal for limeDRIVE in #779
  • [Feature] Add CSV export to customer subscriptions overview in #778
  • [Performance] Push query logging (onlime/laravel-sql-reporter) to the background, using defer() in #777
  • Improve validation Rules test coverage: push to 100% coverage in #776
  • [Bug] SSH pubkey deployment triggered prior to having activated SSH for a hosting in #775
  • [Bug] Cannot add CountrySelect component to CreateDomainModal for country extra data fields in #774
  • [Bug] DomainRegistration/DomainTransfer notifications display outdated domreg data (missing expiry, ns) in #773
  • [Bug] AdminMailing notification does not correctly set Bcc addresses / Fix address merging in MailMessage laravel/framework#55404 in #772
  • [Bug] Make INWX DomainExtraData enum more forgiving (missing MUSIC-ACCEPT-REQUIREMENTS) in #770
  • [Bug] Failing UserSshApprovalControllerTest after shardj/zf1-future 1.24.3 upgrade (Zend_Pdf_Element regression) in #769
  • [Bug] PEST parallel testing fails with Exit Code: 139(Segmentation violation) when using automaticallyEagerLoadRelationships() (Laravel 12.8) in #768
  • Hide Mailinglists in menu for Hostings without mailinglist (Mailman3) addon in #767
  • Generate CHANGELOG.md from release milestones / issues via GitLab API in #766
  • [Performance] Replace md5 with xxhash in #765
  • [Bug] Customer overview hosting list is not refreshed after Hosting creation in #764
  • [Feature] Combined correspondence note for Subscription deletion with addons (child subscriptions) in #762
  • [Bug] Dbbackup stuck in processing state, even though completed in #761
  • [Bug] Fix lazy loading issues when deleting Subscription with child subscriptions in #759
  • [Bug] Traffic stats no longer collected for gt-db (limeDEDICATED custom server) in #758
  • [Bug] Prevent access to Access Stats on limeDRIVE hostings in #757
  • [Feature] Replicate an open BexioInvoice's (Bill) positions (statements) in #756
  • [Bug] Nextbill statements not getting included in invoice in #755
  • Sync updated invoices more frequently on customer bills overview in #754
  • [Bug] Cannot delete a domain which has been transferred away from registrar (INWX) in #753
  • Admin BillingRun: Add full run column incl. filter/sort in #752
  • [Bug] Tailwind CSS 4.1 causes full page reloads / Inertia Link flickering in dev (npm run dev) in #751
  • [Bug] Fix lazy loading issues on full ReDeployHosting command / SiteConfigurator::getMaintenanceData() in #750
  • [Bug] Customer discount not getting applied to renewal Statements in #749
  • Extend DomregContactConsistency command to also fix any mismatching admin/tech/billing contact handles in #748
  • Make DomainRegistrationStatus enum casting more tolerant (handle INWX API undocumented status) in #747
  • Make DomainRegistration notification more tolerant (DomainRunRegistrations command) in #746
  • [Bug] System Dbuser cannot be updated due to prohibited sourcehost validation in #744
  • PR to framework: New HasOneOrMany relation methods: forceCreateMany() + forceCreateManyQuietly in #743
  • [Bug] Fix full billing run schedule (app:invoice-all-customers --full command cron expression) in #742
  • [Bug] MxCheck reactivated Maildomains for 3rd-level domains in #739
  • Improve team permission management in #738
  • [Bug] Domain transfer without transfer cost created a Subscription with CHF 0.00 special_price in #737
  • [Bug] Correspondence timestamp shown in UTC in frontend (datetime TZ issue) in #736
  • [Bug] Restricted Hosting role (stats) can edit webmaster email in #735
  • [Bug] AccessStats middleware is not applied to stats routes (in AccessWeb middleware group) in #734
  • [Bug] New Hosting: webXYZ CNAME not deployed to infrastructure Dnszone onlime.ch.zone in #733
  • [Bug] Cannot set domain on Hosting without domain in #731
  • [Bug] Dnszone deployment did not collect 3rd level subdomains set up as pointings in #730
  • [Bug] ReactDnsService::authoritativeFromDomain() sometimes is unable to resolve NS in full test run in #729
  • Archive full Bexio invoice JSON response body data in #728
  • [Security] bilfeldt/laravel-request-logger does not correctly obfuscate Authorization header in #727
  • Avoid sending out multiple health check failure notifications on same result set in #726
  • Refactor DnsLookup classes / fix DnsLookupFactory mocking in tests in #725
  • Frequent Subscription renewals / Re-organize quarterly billing runs in #724
  • Upgrade docs (Vitepress) to Tailwind v4 in #723
  • [Bug] Fix failing DNS lookups in parallel testing: Replace spatie/dns with react/dns (ReactPHP) in #722
  • [Feature] Show domains in HostingSwitcher in #721
  • [Bug] Fix Addondomain domain redirects with missing Sslcert in #720
  • [Bug] SendInvoices: New invoices were not sent in #719
  • Improve Bexio contact to Customer ID mapping: Store bexio_id on Customer in #718
  • [Bug] BexioSyncUpdatedInvoices: Assets are always synced (updated_at always changed) in #717
  • [Bug] BexioSyncUpdatedInvoices: Bexio contact cannot be mapped to Customer in #716
  • [Feature] Admin Maintenance Tasks: Run Pingen upload (trigger manual Pingen API upload) in #715
  • [UX] Set Reply-To address on PhonestarIncomingVoipCall to ease customer response in #714
  • [UX] Add InfoBox warning on Mailaccount creation modal about empty password in #713
  • [Feature] Admin Maintenance Tasks: Run Mite import time entries (import Statements) in #711
  • bakame/laravel-domain-parser: Improve caching of Public Suffix List in #710
  • [Bug] Sslcert was not attached on Addondomain creation (domain pointing) in #709
  • [Bug] AirpaneAgentApi health check reported: Airpane-agent API: 1 agent(s) not healthy in #708
  • [Bug] Eloquent Setting model accessed too early (while MySQL boots up) in #707
  • [Bug] Fix ScheduledTasksCheck health check: Missed tasks detected (CollectTrafficStats) in #706
  • Admin Task: Pause Billing until (conditional scheduling) in #705
  • [Bug] BexioSyncUpdatedInvoices: Rounding issues of total_gross causes unexpected sync in #704
  • Webhook for Roundcube password plugin driver airpane in #703
  • [Bug] BexioSyncUpdatedInvoices: lost BexioInvoice network_link on some old invoices (+ HTTP 400: you can not send an invoice in a closed business year) in #702
  • [Bug] ValidationRuleParser deprecation: null rule passed to parseStringRule($rule) in #701
  • Laravel 12 Upgrade in #694
  • Add support for catch-all email forwardings (Mailmap) / allow single-character localpart in #686
  • Prevent deployment of all DNS zones on Subdomain create/update (ProcessDeployZonefile job) in #681
  • DnsRecordsConsistency command: Send notifications to webmaster instead of customer email in #678
  • [Bug] INWX Domreg: Why does registration take so long for domain.info (while domain.log is faster) / DomainRunRegistrations fail-safety in #672
  • [Bug] Domain Search: Some TLDs are not recognized as registrable (e.g. .CLOUD, .WORLD, .DIGITAL,...) in #671
  • Store deployed_at timestamp on Hosting / add to Admin maint ReconfigureVhosts task in #666
  • [Bug] Missing path in AuthUserFile on configureVhosts in #655
  • [Bug] Randomly failing DeployHostingTest on full parallel test runs in #642
  • [Feature] Hosting JSON Export/Import in #641
  • Upgrade to TailwindCSS v4.0 in #610

v3.0 (2025-03-05)

  • [Bug] UpdateDiskUsages command logs a lot of Hosting not found on web.onlime.ch for UID: 4XXX in #699
  • [Bug] AuthorizationException: FolderPicker does not work on limeDRIVE in #698
  • Prepare Airpane-staging with anonymized prod data in #697
  • [Bug] Customer triggered multiple SubscriptionCancellation notifications in #696
  • [Bug] DecommissionHosting: Cannot delete web199 / Slow DeleteFpmPool request (disable Systemd service) in #695
  • BexioSyncUpdatedInvoices: HTTP 400 you can not send an invoice in a closed business year in #693
  • SyncBexioInvoicesUnsent: Prevent new BexioInvoices from getting sent to customer if cancelled (at Bexio) in #692
  • Cleanup command for missing Dbbackups (no longer present on filesystem) in #691
  • AuthorizationException: Investigate HTTP 403 on dbbackup web126 (HostingSwitcher) in #690
  • DomainConsistency: Prevent Domreg creation on externally registered domain in #689
  • [Bug] Webmasters getting duplicate/multiple HostingMigratedFromFtpUser notifications (Redirect loop) in #688
  • [Bug] MaintAlignChildSubscriptions also renews child subscriptions of cancelled parents in #687
  • PolicydSync logs warning on every run when a mailaccount is over ratelimit in #685
  • [Bug] INWX RequestExceptionDTO: "The code field is required" (on InwxHealthCheck) in #683
  • [Bug] SslcertFixExpiring incorrect IDN domain name comparison ("Detected inaccurate SAN list") in #682
  • [Bug] Horizon timed out when running ProcessDeployZonefile job (DeployZone request) / Airpane-agent Restarter concurrency in #680
  • [Bug] Cannot delete a domain which is linked, but no longer available at registrar (INWX) / e.g. wlg.ch in #679
  • Upgrade Composer and npm packages in #677
  • [Bug] Subdomain rename fails with HTTP request returned status code 400 (requestCert() causing updated event loop / duplicate Airpane-agent request) in #676
  • [Bug] SieveConsistency command (app:sieve-consistency) times out after 30s in #675
  • [Bug] IDN email issue in CheckMailQuotas command in #674
  • Audits table fills up by CheckQuotaUsages/UpdateDbSizes commands in #673
  • [Bug] Cannot delete a domain which does not exist at registrar (INWX) in #670
  • [Bug] Domain Registration availability check: Premium Domains are show as regular (with regular price) in #669
  • [Bug] INWX Domain Registration: RequestExceptionDTO on .EU registration missing msg field (extraData) in #668
  • [Bug] Prevent redundant subdomain-prefixed domain pointings in ServerAlias in #667
  • [Bug] VirtualHost AuthUserFile htaccess configs missing full path to .htpasswd.* file in #665
  • [Bug] Domain pointings removed from VirtualHost configuration in #664
  • [Bug] ProcessInvoiceAllCustomers: Prevent invoices with 0 total sum in #663
  • [Bug] PostfinanceMftpfParse: The language id field must be a number. in #662
  • [Bug] SSLCertificateKeyFile: file '/etc/letsencrypt/live/xn--zmehappy-0za.ch/privkey.pem' does not exist or is empty in #661
  • [Bug] API Integrations BexioHealthCheck may get 401 Unauthorized: Invalid token. (accessToken not refreshed!) in #659
  • [Bug] PostfinanceMftpfSync and PostfinanceMftpfParse commands don't check for duplicates (camt.054 XML files) in #658
  • [Bug] Scheduled Tasks missed (not skipped) / not always running (Health check) in #657
  • [Bug] BexioSyncUpdatedInvoices: Bexio invoice you can not send an invoice in a closed business year in #656
  • [Bug] DecommissionHosting: Hosting deletion problems in #653
  • [Bug] Hosting creation fails (ProcessCreateHosting -> CreateHostingSubscription action) in #652
  • [Bug] When only adding a domain (without registering): inertiaHelpers.js TypeError: error.response is undefined in #651
  • [Bug] INWX API may return avail: -1 for domain availability / cannot be cast to bool in DomainCheckDTO in #650
  • Improve (Debounce) Hosting Vhosts deployment, prevent duplicate ConfigureVhosts requests in #648
  • [Bug] Airpane-agent hanging on subdomain creation (duplicate request) in #647
  • [Bug] Bexio OpenID auth not working for production app (Airpane-PROD / Airpane-STAGING) in #646
  • [Bug] ExtractQrCodeFromInvoicePdf: Ghostscript (gs) failing on local dev in #645
  • Cleanup: Remove LegacyCustomer model (for Phonestar webhook) in #644
  • User Restoration/Force-Deletion in #643
  • Create MaintDbPull command to pull/load mysqldump from remote in #640
  • Create dummy maint:up command to prevent collision with maint:update-subscription-details command (abbrev best match) in #639
  • PassTeamPermissionsRequest: Filter Hosting IDs for admin Customers in #638
  • Migrate OnboardLayout to the new AuthSplitLayout in #637
  • Fix Cronjobs command CodeBlock width in #636
  • [Bug] Fix IDN Domains for Mailaccount/Mailmap handling in #635
  • Maintenance Tasks: Add System Services card in #634
  • [Bug] Investigate duplicate email verification / Register event triggered twice in #633
  • Improve overall performance on PROD/STAGING (Disable XDebug / OPCache tuning) in #626
  • Failed SyncBexioInvoicesFullYearTest snapshot tests (TZ mismatches with Eloquent timestamps) in #625
  • CreateDomainRequestTest (and other tests) randomly failing in CI / staging in #623
  • Prevent bilfeldt/laravel-request-logger from polluting logs (correlation_id + request_id) in #617
  • Scheduled tasks: Implement missing commands (rewrite from airpane-zf1) in #614
  • [Bug] Missing Menu/CustomerSwitcher/HostingSwitcher when leaving impersonation in #601
  • PHP Config Manager: Lower max_execution_time limit to 240s (+ limit PHP FPM-pools to request_terminate_timeout = 240s) in #586
  • Improve maintenance mode for Inertia in #581
  • [Bug] Empty traffic data breaks the TrafficStats graph / Make SplineArea (Apexcharts) more forgiving on empty data in #577

v3.0-rc1 (2025-02-08)

  • Resolve PHP 8.4 error_reporting confusion (~E_STRICT by default) in #632
  • Introduce Http\Client\RequestException dontTruncateRequestExceptions() (since Laravel 11.35) in #631
  • [Bug] Fix HandlesStreams::deliverStream() helper for DB backup downloads (and more) in #629
  • Anonymize PROD data for local profiling in #627
  • Fix SiteConfigurator eager loading: Refactor Hosting/Subdomain pathes in #624
  • Improve Sshkey manager in Admin Area / CrudList in #622
  • [Bug] AutoApproveSshkeys broken on production data with missing user relation in #621
  • Add X-Metadata-Command and X-Tag headers to scheduled task email output in #620
  • Jobs & DB Transactions: Enable after_commit globally (or ShouldDispatchAfterCommit) in #618
  • Prunable Dnsrecord for expired system DNS records (DKIM keys) in #616
  • Improve/Refactor active state handling (HasActiveFlag trait) in #613
  • Hosting Suspension in #612
  • FormSlider: Replace @vueform/slider by Radix Vue Slider in #611
  • [Bug] SiteConfigurator::getFullVirtualHostsData(): Lazy loading problem with primaryFtpUser in #609
  • Simplify/Refactor HasCommandLogger (or legacy HasActionOutput) to the new WritesToLog trait in #608
  • Admin maint command for Apache::configureAllVhosts() in #607
  • Mailaccount quota warnings (CheckMailQuotas command) in #605
  • Refactor EmailStrict / EmailRelaxed custom validation rules to Fluent Email Rule in #603
  • [Bug] Bottom of SidebarNavigation menu not accessible on mobile in #602
  • Upgrade to Vite v6.0.9 / Security fix (prevent DNS rebinding attacks) in #600
  • Maint command to change dbprefix of a Hosting in #599
  • Optimize Hosting::configureVhosts() / too many SELECT queries in #598
  • [Bug] Inertia v2 deferred props break Ziggy route() in #597
  • Global Mail Notification recipient address filtering (dummy recipients) in #592
  • [Bug] Sslcert should not be requested on limeDRIVE / Handle Subdomains with missing Sslcert in #591
  • Prepare PROD/STAGING deployments in #590
  • [Bug] Caching / asset version / Outdated (non-reactive) breadcrumbs in #588
  • Fix HelpSlideover cached iframe content in #587
  • [Bug] ModelNotFoundException flash message when trying to switch to another Hosting in #585
  • Hosting Overview in #583
  • Truncation of HTTP Client Request Exceptions in #579
  • [Bug] CrudList query param per_page=15 after logging out in #576
  • Customer correspondences (attach notes to customers) in #574
  • Fix: HelpSlideoverLink in BaseLayout no longer reactive in #571
  • Upgrade to Vite v6.0 in #558
  • [Bug] Inertia v2 History Encryption breaks Ziggy in #554
  • Improve / beautify maintenance mode (DownCommand) in #553
  • Broken webhook routes in #550
  • Add TeamSwitcher to Onboarding (onboard.index) in #545
  • Laravel Horizon for job queues in #529
  • Customer Newsletter/Mailing (Admin Area) in #528
  • GoAccess Sites Deployment (prod webservers) in #524
  • Upgrade to Inertia 2.0: Use new features (Async requests, WhenVisible, Polling) in #518
  • UI Layout (Navigation menu / header) redesign in #508