fix: keep the auto-reply running when filters are saved on the phone

Stalwart runs one active Sieve script and turns the auto-reply on by
activating its own `vacation` script. The webmail therefore re-activates
the filters script with `include :personal :optional "vacation"` and
records `includeVacation` in the rules metadata (198a3c0d). The phone
dropped both, so saving any filter on the phone silently switched the
auto-reply off, and turning the auto-reply on from the phone switched
every filter off.

Port the webmail's handling:
- the generator writes the include (and `require "include"`) and the
  parser reads the flag back, dropping the `include` require once the
  auto-reply is off;
- loading filters while the vacation script is active keeps it through
  the include, as does every save;
- switching the auto-reply on or off in the vacation settings adds or
  removes the include, and the settings read the include as "on",
  because VacationResponse reports it off in that state;
- the "vacation active" banner also shows for an include.

Scripts the webmail wrote with the include now save back unchanged;
`fixtures/webmail/` holds scripts from its current generator.
This commit is contained in:
Linus Rath
2026-09-24 19:29:36 +02:00
parent 4fdf39aa08
commit d53bfec68a
11 changed files with 393 additions and 13 deletions
+2 -2
View File
@@ -142,7 +142,7 @@ export function FilterSettings({ onOpenVacation }: FilterSettingsProps = {}) {
const vacationEnabled = useVacationStore((s) => s.accountId === null && s.isEnabled);
const {
rules, isLoading, isSaving, error, isSupported, isOpaque, rawScript, vacationSettings,
rules, isLoading, isSaving, error, isSupported, isOpaque, rawScript, vacationSettings, includeVacation,
selectAccount, saveFilters, addRule, updateRule, deleteRule, reorderRules, toggleRule,
setOpaqueScript, resetToVisualBuilder, validateScript,
} = useFilterStore();
@@ -163,7 +163,7 @@ export function FilterSettings({ onOpenVacation }: FilterSettingsProps = {}) {
}, [managedAccountId, selectAccount]);
const showVacationBanner =
!managedAccountId && ((vacationEnabled || vacationSettings?.isEnabled) ?? false);
!managedAccountId && ((vacationEnabled || vacationSettings?.isEnabled || includeVacation) ?? false);
// Editable (Bulwark-managed) rules, in order, for reorder math.
const editableIds = useMemo(