mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 08:06:36 +00:00
fix: stop notifications fetching sender favicons when favicons are off
The "Sender Favicons" setting only covered the in-app avatars. Push notifications always fetched the sender's favicon from icons.duckduckgo.com, so with the setting off every notification still sent the sender's domain and the device's IP to a third party. The webmail has the same setting, on by default, and fetches through its own `/api/favicon` proxy, so DuckDuckGo sees the server rather than the user. Native has no proxy, but turning the default off would silently drop the logos existing users see and diverge from the webmail, which is a product call. So the default stays on and the one existing switch now covers every favicon fetch: the notification task reads it from the persisted settings and shows initials when it is off, or when the settings cannot be read.
This commit is contained in:
@@ -10,10 +10,12 @@ vi.mock('../../api/jmap-client', () => ({
|
||||
vi.mock('../client-cert', () => ({ secureFetch: vi.fn(async () => ({ ok: false, status: 500 })) }));
|
||||
vi.mock('../oauth', () => ({ refreshOAuthAccessToken: vi.fn(async (t: unknown) => t) }));
|
||||
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import {
|
||||
matchAccountsForPush,
|
||||
parseRelayPushData,
|
||||
selectNotifiableEmails,
|
||||
senderFaviconsAllowed,
|
||||
} from '../push-background-task';
|
||||
import type { Email } from '../../api/types';
|
||||
|
||||
@@ -88,3 +90,22 @@ describe('selectNotifiableEmails', () => {
|
||||
expect(out.map((e) => e.id)).toEqual(['a']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('senderFaviconsAllowed', () => {
|
||||
const KEY = 'webmail:settings:v1';
|
||||
|
||||
it('follows the "Sender Favicons" setting the settings store persisted', async () => {
|
||||
await AsyncStorage.setItem(KEY, JSON.stringify({ senderFavicons: false }));
|
||||
expect(await senderFaviconsAllowed()).toBe(false);
|
||||
await AsyncStorage.setItem(KEY, JSON.stringify({ senderFavicons: true }));
|
||||
expect(await senderFaviconsAllowed()).toBe(true);
|
||||
});
|
||||
|
||||
it('defaults to on like the store, but skips icons when the settings are unreadable', async () => {
|
||||
await AsyncStorage.removeItem(KEY);
|
||||
expect(await senderFaviconsAllowed()).toBe(true);
|
||||
await AsyncStorage.setItem(KEY, '{not json');
|
||||
expect(await senderFaviconsAllowed()).toBe(false);
|
||||
await AsyncStorage.removeItem(KEY);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -42,6 +42,7 @@ const EMAIL_PROPERTIES = [
|
||||
|
||||
interface PushPersistedSettings {
|
||||
emailNotificationsEnabled?: boolean;
|
||||
senderFavicons?: boolean;
|
||||
}
|
||||
|
||||
async function emailNotificationsAllowed(): Promise<boolean> {
|
||||
@@ -55,6 +56,20 @@ async function emailNotificationsAllowed(): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
// The "Sender Favicons" setting covers notification icons as well as the
|
||||
// in-app avatars: with it off the tray shows initials, and the sender's domain
|
||||
// and the device's IP never reach the icon service. Off when unreadable.
|
||||
export async function senderFaviconsAllowed(): Promise<boolean> {
|
||||
try {
|
||||
const raw = await AsyncStorage.getItem(SETTINGS_STORAGE_KEY);
|
||||
if (!raw) return true; // first launch: the store's default is on
|
||||
const parsed = JSON.parse(raw) as PushPersistedSettings;
|
||||
return parsed.senderFavicons !== false;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
interface ShowNotificationOptions {
|
||||
notificationId: string;
|
||||
title: string;
|
||||
@@ -429,6 +444,7 @@ async function processAccountForPush(accountId: string, payload: RelayPushData):
|
||||
|
||||
const groupKey = `bulwark-mail:${accountId}`;
|
||||
const groupTitle = payload.accountLabel ?? accountId.split('@')[0] ?? accountId;
|
||||
const favicons = await senderFaviconsAllowed();
|
||||
|
||||
// Oldest first so the newest ends up on top of the tray.
|
||||
const ordered = [...toNotify].sort(
|
||||
@@ -442,7 +458,7 @@ async function processAccountForPush(accountId: string, payload: RelayPushData):
|
||||
const body = email.subject || '(no subject)';
|
||||
const initials = getEmailInitials(name, address);
|
||||
const bgColorHex = hslToHex(generateEmailAvatarColor(name, address));
|
||||
const faviconDomain = getFaviconDomain(address);
|
||||
const faviconDomain = favicons ? getFaviconDomain(address) : null;
|
||||
const iconUrl = faviconDomain ? getFaviconUrl(faviconDomain) : undefined;
|
||||
|
||||
await native.showNotification({
|
||||
|
||||
Reference in New Issue
Block a user