feat: skip server-managed vacation script in Sieve script handling
This commit is contained in:
@@ -339,5 +339,39 @@ describe('filter-store', () => {
|
||||
await useFilterStore.getState().fetchFilters(mockClient as unknown as IJMAPClient);
|
||||
expect(useFilterStore.getState().rawScript).toBe(script);
|
||||
});
|
||||
|
||||
it('should skip the server-managed vacation script', async () => {
|
||||
const { generateScript } = await import('@/lib/sieve/generator');
|
||||
const rules = [makeRule({ name: 'MyFilter' })];
|
||||
const script = generateScript(rules);
|
||||
|
||||
const mockClient = {
|
||||
getSieveCapabilities: () => null,
|
||||
getSieveScripts: async () => [
|
||||
{ id: 'vac-1', name: 'vacation', blobId: 'bv', isActive: true },
|
||||
{ id: 's1', name: 'filters', blobId: 'b1', isActive: false },
|
||||
],
|
||||
getSieveScriptContent: async (blobId: string) => {
|
||||
if (blobId === 'b1') return script;
|
||||
return 'require "vacation"; vacation "I am away";';
|
||||
},
|
||||
};
|
||||
await useFilterStore.getState().fetchFilters(mockClient as unknown as IJMAPClient);
|
||||
// Should pick the 'filters' script, not the 'vacation' one
|
||||
expect(useFilterStore.getState().activeScriptId).toBe('s1');
|
||||
expect(useFilterStore.getState().rules[0].name).toBe('MyFilter');
|
||||
});
|
||||
|
||||
it('should handle only vacation script present (no filter scripts)', async () => {
|
||||
const mockClient = {
|
||||
getSieveCapabilities: () => null,
|
||||
getSieveScripts: async () => [
|
||||
{ id: 'vac-1', name: 'vacation', blobId: 'bv', isActive: true },
|
||||
],
|
||||
};
|
||||
await useFilterStore.getState().fetchFilters(mockClient as unknown as IJMAPClient);
|
||||
expect(useFilterStore.getState().activeScriptId).toBeNull();
|
||||
expect(useFilterStore.getState().rules).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,8 +52,12 @@ export const useFilterStore = create<FilterStore>()((set, get) => ({
|
||||
const capabilities = client.getSieveCapabilities();
|
||||
set({ sieveCapabilities: capabilities });
|
||||
|
||||
const scripts = await client.getSieveScripts();
|
||||
debug.log('Sieve scripts fetched:', scripts.length);
|
||||
const allScripts = await client.getSieveScripts();
|
||||
debug.log('Sieve scripts fetched:', allScripts.length);
|
||||
|
||||
// Skip the server-managed 'vacation' script (RFC 9661 §4) — it can only
|
||||
// be modified via VacationResponse/set, not SieveScript/set.
|
||||
const scripts = allScripts.filter(s => s.name !== 'vacation');
|
||||
|
||||
const activeScript = scripts.find(s => s.isActive) || scripts[0];
|
||||
if (!activeScript) {
|
||||
@@ -163,7 +167,9 @@ export const useFilterStore = create<FilterStore>()((set, get) => ({
|
||||
|
||||
// Always re-fetch scripts from the server to get the current state
|
||||
// after Stalwart may have rewritten the active script.
|
||||
const scripts = await client.getSieveScripts();
|
||||
const allScripts = await client.getSieveScripts();
|
||||
// Skip the server-managed 'vacation' script (RFC 9661 §4)
|
||||
const scripts = allScripts.filter(s => s.name !== 'vacation');
|
||||
const activeScript = scripts.find(s => s.isActive) || scripts[0];
|
||||
|
||||
let rules = previousRules;
|
||||
|
||||
Reference in New Issue
Block a user