Skip to content

Fix/cleanup after addressbook deletion#56

Merged
ralflang merged 4 commits into
FRAMEWORK_6_0from
fix/cleanup_after_addressbook_deletion
May 25, 2026
Merged

Fix/cleanup after addressbook deletion#56
ralflang merged 4 commits into
FRAMEWORK_6_0from
fix/cleanup_after_addressbook_deletion

Conversation

@TDannhauer

Copy link
Copy Markdown
Contributor

Clean up sync_books when address books are deleted

Summary

  • Remove deleted address book IDs from the sync_books user preference automatically on every delete path (web UI, API/RPC, and automatic vbook removal).
  • Reset ActiveSync contact folder state when sync_books changes, matching the existing behavior for manual preference edits.
  • Self-heal stale sync_books entries on the next contact sync instead of failing with Invalid address book.

Problem

Turba stores the list of address books to export via ActiveSync in the sync_books preference. When a new book is created through ActiveSync, addAddressbook() appends its share ID to that list — but none of the delete paths removed the ID again.

The preferences UI only displays books that still exist, so stale IDs can remain in the stored preference unnoticed. On the next contact sync, _getSources() loaded the preference and threw Invalid address book: <id>. ActiveSync logged the error and returned an empty contact list (Status 1, no POOMCONTACTS data), which manifested as empty contacts in Outlook while mail and calendar continued to work.

Solution

  1. Turba_Api::removeSyncBook($id) — remove one share ID from sync_books; if the preference changed, call the ActiveSync contact state reset.
  2. Turba_Api::resetActiveSyncContactsState($notify) — centralize the device state reset previously duplicated in config/prefs.php on_change.
  3. Call removeSyncBook() from all delete paths:
    • Turba_Api::deleteAddressbook() (RPC / ActiveSync connector)
    • Turba_Form_DeleteAddressBook::execute() (web UI)
    • Turba::getConfigFromShares() (automatic removal of orphaned virtual address books)
  4. Turba_Api::_getSources() — when loading from sync_books, skip IDs that no longer exist in $cfgSources, persist the pruned list, and continue with valid books. Explicit caller-supplied source IDs still fail fast with an exception.

Files changed

File Change
lib/Api.php New removeSyncBook(), resetActiveSyncContactsState(); cleanup in deleteAddressbook(); self-healing in _getSources()
lib/Form/DeleteAddressBook.php Call removeSyncBook() before removeShare()
lib/Turba.php Call removeSyncBook() when removing orphaned vbooks
config/prefs.php Refactor sync_books on_change to use resetActiveSyncContactsState(true)

Test plan

  • Create an address book with ActiveSync sync enabled; confirm it appears in sync_books (Turba preferences or DB).
  • Delete that address book via the Turba web UI; confirm its ID is removed from sync_books and ActiveSync devices receive a resync notification.
  • With two books in sync_books, delete one; confirm the remaining book still syncs contacts to Outlook/iOS.
  • Manually insert a non-existent share ID into sync_books; trigger a contact sync; confirm the stale ID is pruned, sync succeeds, and no Invalid address book error appears in the ActiveSync log.
  • Change sync_books manually in Turba preferences; confirm ActiveSync contact state is still reset and the success notification is shown (unchanged behavior, refactored implementation).
  • Delete an address book via the API (contacts/deleteAddressbook RPC) if available; confirm the same sync_books cleanup occurs.

@TDannhauer TDannhauer requested a review from ralflang May 24, 2026 20:27
@ralflang ralflang merged commit 6bc79f0 into FRAMEWORK_6_0 May 25, 2026
0 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants