## [1.6.1] - 2026-10-12 ### Added - A CalDAV section under Settings / Integrations, where the connection URLs that may point into the local network are listed - The calendar page now explains why a CalDAV synchronization failed and what has to be corrected, instead of only reporting that it did - Connecting to a CalDAV server on a local network now offers to allow its host right in the connection dialog, instead of requiring a trip to the settings; the host is only remembered once the connection actually works ### Changed - Changing the password in the account settings page now requires the current password, so that a stolen session alone cannot be used to take over the account - The CORS origins and the cookie SameSite policy are now set in application/config/routes.php and application/config/config.php, instead of the root config.php, which keeps only the installation settings - The release build now falls back to running Composer inside the php-fpm container, so a Composer installation on the host machine is no longer required - The release package no longer includes stylesheet sources, dependency development files and unused images, which makes the download smaller ### Fixed - Removing every provider from a service on the services page is now saved, instead of silently keeping the previous provider assignments (#1965) - The asset and release build no longer fails with permission errors on the files that the Docker containers create in the project directory - A failing Google Calendar synchronization no longer removes the local appointments of the sync period, so an expired token, a quota limit or an unreachable API only interrupts the sync - Appointment notes are no longer overwritten with the generated provider and customer details block on every CalDAV synchronization - CalDAV events that are stored under an address that does not match their UID are now found, so events created in a calendar client are no longer removed and imported again on every synchronization - Synchronizing one provider no longer removes the imported recurring CalDAV events of the other providers - Moving an appointment to another provider now removes the event from the calendars of the previous provider - The CalDAV synchronization period is now requested in UTC, so events at the edges of the period are no longer left out on installations that do not run in UTC - Google Calendar and CalDAV are now synchronized independently, so a failure of one of them no longer skips the other - The Google Calendar synchronization now fails with a clear error when the provider has no refresh token stored - Security: The Google Calendar API requests now verify the TLS certificate of the remote endpoint - Security: CalDAV connections no longer follow redirects or server links to other hosts, and no longer reach private addresses through IPv6 transition addresses or a DNS answer that changes after the check - HTML texts, such as the privacy policy and the terms & conditions, are now purified with a cache directory inside storage/cache, so installations with a read-only vendor directory no longer fail with a write error - The list of Google Calendars of a provider is no longer readable without permission, so only that provider or a user who may edit providers can fetch it - Searching the LDAP directory now escapes the keyword, so a search term can no longer alter the LDAP filter - Webhooks created or edited through the REST API can now set their secret header, so the secret token is sent with the request as it already is for webhooks configured in the backend - Security: Updated the Guzzle HTTP client and the phpseclib library to their patched releases, fixing outbound request and certificate handling advisories that affected the webhook, CalDAV and Google Calendar integrations - Editing a working plan exception now updates the existing entry, instead of adding a duplicate one next to it (#1958) - Google Calendar events marked as "Free" no longer block booking, so all-day events and birthdays stay bookable (#1945) - CalDAV Calendar events marked as free (TRANSP:TRANSPARENT) no longer block booking (#1945) - Providers and secretaries can no longer overwrite or reassign the appointments and unavailabilities of other providers - Requests with invalid parameters now respond with a "bad request" status instead of a server error - Services can no longer be saved with a negative price or with a slot interval of zero - The price, slot interval and attendants number of a service are now checked before the form is submitted - Show a message with the affected days when the working plan of a provider has an invalid time range - Ask for a confirmation when an unavailability is placed over an already booked appointment - The appointment dialog now validates the phone number, just like the booking page does - Timezone labels display the offset that is currently in effect, also during daylight saving time - The timezone list no longer contains duplicate names, deprecated entries or malformed offsets - When saving an appointment, the scheduling conflict is now confirmed before the notification question - The scheduling conflict dialog of a new appointment is not titled "Appointment Update" anymore - Show a message on the booking page when no service or provider has been selected yet - The appointment dialog scrolls to its validation message and clears invalid fields while typing - Fix the "Start date value is latter than end date." and "The operation could not completed." messages - Security: The CalDAV and Google Calendar sync settings of a provider can no longer be reached without logging in first - Security: CalDAV URLs that point into the local network are rejected again, unless the host is listed in the new CalDAV integration settings - Security: The CAPTCHA can no longer be skipped by leaving the field out of the login, recovery or booking request - Security: Login attempts are throttled again, so repeated wrong passwords are blocked as intended - Security: Stop unauthorized users from taking over or changing other people's appointments - Security: Block unsafe links in the online meeting field so they cannot run code on the calendar - Security: Stop the calendar from returning the Google Calendar tokens and CalDAV passwords of providers to secretary accounts - Security: Stop the user management pages from returning the calendar sync tokens, CalDAV passwords and password reset tokens of other accounts - When rescheduling an appointment, its date and time are selected again by default (#1940) - Rescheduling an appointment can be saved again, instead of failing with an appointment hash error - Show the cancel appointment text and button on a single line with even spacing - Fix the automated test setup - The provider and secretary "Mobile" number is now saved when you create or edit them - Fix a booking error that appeared when the booking page was embedded on another website - Fix a language switch error when the booking page was embedded on another website - The booking page now works when embedded on other websites - Show a clear message when the database needs to be updated, instead of a confusing error - Fix the month switching on the booking calendar (#1862) - Show appointment notes correctly in email notifications (#1881) - Google Meet link is created but never stored in appointments.meeting_link (#1947) - Security: Protected settings, such as the API token, can no longer be read or changed through the REST API by writing their name in a different letter case - Security: An ID in the body of a REST API update request no longer redirects the update to another record, such as an administrator account, than the one in the URL - Security: Saving or deleting a provider, secretary or admin now only affects users of that role, so an administrator account can no longer be overwritten or deleted, or a role changed, through another user type - Security: A new booking can no longer be placed on an already booked time slot by sending the ID of the existing appointment along with the booking request - Security: With limited customer access, providers and secretaries can no longer edit or book appointments for customers they have no appointments with through the calendar page - Enabling ALTCHA without generating an HMAC key no longer rejects every login and booking, the key is now created and stored on first use - The customer data retention cleanup now removes inactive customers again, instead of removing none of them whenever an unavailability ends after the retention cutoff - Two short blocked periods on the same day no longer hide all the available hours of that day on the booking page - Services with multiple attendants no longer offer a time slot that contains a shorter appointment of the same provider, which led to double bookings - Security: A solved CAPTCHA image is now only valid for one attempt, so it can no longer be reused for repeated login, password recovery or booking requests - Security: Deleting or viewing a customer from the backend now only works for customer accounts, so a provider or secretary can no longer delete or read the account of an admin or another staff member - Security: The appointment details on the booking confirmation step are now escaped, so HTML in a service or provider name can no longer run scripts in the customer's browser - Adding or editing an unavailability from the unavailabilities page no longer fails with a server error, and deleting one now also removes it from the synchronized Google Calendar or CalDAV calendar - Dates that do not exist, such as February 30, are now rejected when saving appointments, unavailabilities and blocked periods, instead of being silently stored as a different date ## [1.6.0] - 2026-05-27 ### Added - Added request method check on each request so that only allowed methods are accepted - Add Jitsi integration and link generation for appointments made via the public page - Allow providers to toggle the syncing themselves (#1731) - Add new meeting link field to appointments for storing online video conference locations - Create new integration section for the Google Calendar integration (#1690) - Add settings to not display the Add to Google Calendar button in the booking confirmation page (#1763) - Add new Google Meet setting and meeting link support for appointments while syncing with Google (#1589) - Add Select All / None buttons to multi-checkbox fields - Add prompt for client notifications so that they are not sent every time an appointment changes - Add notification prompt when creating new appointments from the calendar page - Add notification prompt when deleting appointments from the calendar page - Connect RSS updates from the official blog and show them in the about page - ALTCHA integration added as an alternative CAPTCHA step (#1155) - Add a legal notice and imprint links to the booking page and the legal settings page (#1407) - When someone clicks on password reset, implement a link delivery and not just change the password directly - Login / Backend button on the disabled booking page message screen (#1777) - Allow customers to save their information in local storage (#1696) - Implementation of additional GDPR features in Easy!Appointments (#535) - Allow users to define working plan exceptions for multiple dates (#1706) - Add CAPTCHA support for all the public forms in order to block abusive requests (#1754) - Add validation when saving the working plan (#1758) ### Changed - Improved CRUD list entries to show pointer cursor when selected - Centered and narrowed CRUD list and form content on larger screens for better readability - Refactored cleanup logic from Console controller into a dedicated Cleanup library - Make the phone number field of backend users optional (#1709) - Change the main CRUD layout and navigation structure (list first) - Replace the availabilities type with the new slot interval field - Keep the provider option selected in the booking page if possible (#1672) - Improve setting language by GET parameter (#1620) - Improved appointment deletion flow: ask notification question first, only show the cancellation reason dialog when the user chooses to notify users - Restyled secondary action buttons (Cancel, Close) to use the outline secondary variant for a consistent UI - Simplified all documentation pages for better readability by non-technical users - Allow users to assign a provider to the service in the services page and update the label (assign the service to) - Perform various security optimizations in the app - Custom fields are displayed in appointment details popup (#1830) - When booking in calendar add a new check that will detect if the selected provider is still available or not - If the current user has not available services or providers to be displayed in the public booking page, then show an info message instead of the booking page ### Fixed - Release builds now ship only the Google Calendar service instead of every Google API service, keeping the download size small - Language switching now works for languages with hyphenated codes such as Brazilian Portuguese and Traditional Chinese - Added missing language code mappings for Brazilian Portuguese and Traditional Chinese - Working plan exception break inputs now use the correct size and no longer look oversized - "No breaks" placeholder is now removed when the first break is added to a working plan exception - Account page can now be saved when the phone number field is left empty - Booking cancellation no longer shows a success page when the appointment was not actually deleted - Booking cancellation no longer fails because of a security check mismatch on public booking routes - Booking cancellation error page now shows the real reason (for example "rate limit exceeded") instead of a generic "appointment not found" message - Booking cancellation no longer crashes when the cache is unavailable - Old session files are now cleaned up properly - Added automatic cleanup of cache, sessions and logs older than 90 days - Appointments can now be modified after a provider changes their time zone (#1789) - Customer appointment link in the table calendar view now opens the appointment modal as expected - The session garbage collector now runs periodically to prevent session storage bloat (#1793) - Providers can no longer pick customers they are not connected with when the customer visibility limit is enabled - Improved CalDAV syncing compatibility with more calendar systems (#1840) - Optimized backend queries during the booking process (#1721) - Added the sequence field to the ICS file so calendar apps correctly update appointments after multiple changes - Creating a "new" customer from the backend calendar appointment modal now reuses the existing customer record when the same email already exists - Login page username and password fields now keep proper spacing between the icon and the typed text - Password recovery and password reset form inputs now keep proper spacing between the icon and the typed text - Bottom toast notifications on mobile are now centered horizontally instead of being stuck to the left edge - Fixed a security issue where an administrator could inject scripts into the "booking disabled" message that would then run for every visitor of the public booking page - Fixed a security issue where a provider could create or modify appointments under another provider's account - Fixed a security issue where the CalDAV connection test could be abused to reach internal services on the server's network or leak error details from those services - The CalDAV safety check is now enabled by default and can be toggled inside the CalDAV library, with the local Docker test server always allowed so local setups can still test the integration - Fixed a security issue where a backend user could hijack another provider's Google Calendar sync by linking it to their own Google account - Fixed a warning that appeared in some availability API responses when booking-window settings were left empty - The time picker inside the working plan exception break editor is no longer cropped by the modal and now shows the full dropdown - Fixed a privacy issue where the appointment reschedule page exposed more customer details (email, phone, address, custom fields, etc.) than needed; only the customer's name is now embedded in the page - The page header now correctly picks up the configured company color on themes that previously kept a hardcoded blue border - The custom company color no longer overrides theme styles on buttons, forms, menus, dropdowns, alerts and lists, so the selected theme keeps its intended look - The "Booking Link" label next to the link icon on the Providers and Services pages was replaced with a tooltip on hover for a cleaner look - Calendar table view filters now lay out cleanly on mobile, with the provider and service filters on their own rows below the date controls - Calendar month view day numbers no longer appear underlined or in the link color - Webhooks are now triggered only for the exact actions they are subscribed to, instead of matching similarly named actions by substring - Google Calendar sync no longer silently drops events from large calendars (more than ~250 events); the sync now pages through all events - Fixed a parse error in the Italian, Catalan, French and Luxembourgish translations of the CAPTCHA warning message caused by unescaped apostrophes - Flatpickr month picker no longer cuts off the bottom of month names with descenders - Corrected the "notify users on update" question translation in 40 non-English language files so it matches the intended English meaning - Fixed an error when deleting personal information from the Privacy page on installations where the cache is unavailable - Read-only and disabled form fields are now readable on dark themes - Dark themes are no longer overridden by a light page background, even when a custom company color is configured - Improved the contrast of the secondary color on the Darkly theme so buttons, links and text are easier to read - Section headings on CRUD and settings pages (e.g. "Details") are now readable on dark themes - Cards on the services, providers, secretaries, customers and integrations pages now follow the theme background instead of being forced to white - Form inputs on the Materia theme now show the Material-style underline on focus instead of a full border (also fixes related visual glitches on Cosmo alerts and Darkly/Flatly pagination) - The dropdown caret is now visible on timezone selects and the Google Calendar sync select across all themes - Filter list hover background is now readable on dark themes ### Removed - Remove the patch.php file ## [1.5.2] - 2025-08-25 ### Fixed - Fix the GTag script URL html rendering (#1666) - Fix the "Load More" JS error in secretaries page (#1677) - Fix the PHP compatibility error of the appointments index API endpoint (#1678) - Catch individual email delivery exceptions (#1670) - Apply permission checks to the appointment and unavailability search (#1753) - Make sure the sync button is visible on provider log in (#1749) - Update unavailable dates after applying appointment data while rescheduling (#1662) - Make sure that any-provider does not include hidden providers while generating availability (#1733) - Provide "text" version of the emails in addition to HTML (#1711) - Trigger webhook requests when managing records via the API (#1676) ## [1.5.1] - 2025-01-20 ### Added - Add support for PHP 8.4 (#1640) - Add new secret token header field to webhooks and default to X-EA-Token (#1607) - Add company colors to notifications (#1569) - Add Albanian Language Translations (#1646) ### Fixed - Fix the date parsing issue on Safari web browsers during the booking process (#1584) - Fix working plan configuration am/pm hour parsing so that it works in all languages (#1606) - Improve the CalDAV syncing mechanism so that it connects to more systems without problems (#1622) - Fix various 1.5.0 API issues (#1562) - Correct email issues by replacing the internal email library with phpmailer (#1587) - Fix ICS file mimetype (#1630)∏ - Incorrect Timezone Handling in CalDAV Synchronization Causes Time Shifts (#1626) - No color change in the appointment modal window (in the backend calendar) (#1641) - The plain user password might appear in the log messages in case of an error (#1590) - Fix loop when going a month back in an edge case (#1577) - Dedicated provider links do not pre-select the relevant provider on the booking page (#1651) - Correct the service / provider booking header display (#1650)