diff --git a/lib/__tests__/push-preferences.test.ts b/lib/__tests__/push-preferences.test.ts index c1063835f..47a08b510 100644 --- a/lib/__tests__/push-preferences.test.ts +++ b/lib/__tests__/push-preferences.test.ts @@ -31,6 +31,20 @@ describe('writePushPreferences', () => { await expect(writePushPreferences({ sound: true })).resolves.toBeUndefined(); expect(put).not.toHaveBeenCalled(); }); + + it('does nothing where reading the Cache store throws', async () => { + // A plugin sandbox frame has an opaque origin: reading `caches` there, + // typeof included, throws a SecurityError. + Object.defineProperty(globalThis, 'caches', { + configurable: true, + get() { + throw new DOMException('Cache storage is disabled because the context is sandboxed', 'SecurityError'); + }, + }); + const { writePushPreferences } = await import('../push-preferences'); + await expect(writePushPreferences({ sound: true })).resolves.toBeUndefined(); + expect(put).not.toHaveBeenCalled(); + }); }); describe('settings store push preference mirror', () => { diff --git a/lib/push-preferences.ts b/lib/push-preferences.ts index fe8aa3c7e..a148e34a9 100644 --- a/lib/push-preferences.ts +++ b/lib/push-preferences.ts @@ -21,8 +21,11 @@ export function pushPreferencesKey(origin: string): string { } export async function writePushPreferences(prefs: PushPreferences): Promise { - if (typeof window === 'undefined' || typeof caches === 'undefined') return; + if (typeof window === 'undefined') return; try { + // A frame sandboxed without allow-same-origin (the plugin sandbox loads + // the settings store too) throws on any read of `caches`, typeof included. + if (typeof caches === 'undefined') return; const cache = await caches.open(PUSH_STATE_CACHE); await cache.put( pushPreferencesKey(window.location.origin),