diff --git a/apps/weblibre/assets/preferences/settings.json b/apps/weblibre/assets/preferences/settings.json index e775c38d..e98db435 100644 --- a/apps/weblibre/assets/preferences/settings.json +++ b/apps/weblibre/assets/preferences/settings.json @@ -3,14 +3,6 @@ "Safe Browsing": { "description": "Google Safe Browsing warns users about dangerous websites and downloads.", "preferences": { - "browser.safebrowsing.malware.enabled": { - "value": true, - "title": "Enable malware protection" - }, - "browser.safebrowsing.phishing.enabled": { - "value": true, - "title": "Enable phishing protection" - }, "browser.safebrowsing.downloads.remote.enabled": { "value": false, "title": "Disable remote verification for downloads", diff --git a/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.dart b/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.dart index 5760470e..3dc34acc 100644 --- a/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.dart +++ b/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.dart @@ -31,6 +31,9 @@ import 'package:weblibre/features/user/domain/repositories/general_settings.dart part 'engine_settings_replication.g.dart'; +const _safeBrowsingMalwarePref = 'browser.safebrowsing.malware.enabled'; +const _safeBrowsingPhishingPref = 'browser.safebrowsing.phishing.enabled'; + /// Checks if any Custom ETP setting changed between two EngineSettings instances. bool _customEtpSettingsChanged( GeckoEngineSettings? previous, @@ -229,6 +232,24 @@ class EngineSettingsReplicationService .read(preferenceFixatorProvider.notifier) .register('pdfjs.disabled', !settings.enablePdfJs); } + if (previous.value?.safeBrowsingMalwareEnabled != + settings.safeBrowsingMalwareEnabled) { + await ref + .read(preferenceFixatorProvider.notifier) + .register( + _safeBrowsingMalwarePref, + settings.safeBrowsingMalwareEnabled, + ); + } + if (previous.value?.safeBrowsingPhishingEnabled != + settings.safeBrowsingPhishingEnabled) { + await ref + .read(preferenceFixatorProvider.notifier) + .register( + _safeBrowsingPhishingPref, + settings.safeBrowsingPhishingEnabled, + ); + } if (!const DeepCollectionEquality.unordered().equals( previous.value?.locales, settings.locales, @@ -283,6 +304,18 @@ class EngineSettingsReplicationService await ref .read(preferenceFixatorProvider.notifier) .register('pdfjs.disabled', !settings.enablePdfJs); + await ref + .read(preferenceFixatorProvider.notifier) + .register( + _safeBrowsingMalwarePref, + settings.safeBrowsingMalwareEnabled, + ); + await ref + .read(preferenceFixatorProvider.notifier) + .register( + _safeBrowsingPhishingPref, + settings.safeBrowsingPhishingEnabled, + ); await ref .read(preferenceFixatorProvider.notifier) .register('intl.accept_languages', settings.locales.join(',')); diff --git a/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.g.dart b/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.g.dart index 74f8b29b..3b20dbe7 100644 --- a/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.g.dart +++ b/apps/weblibre/lib/features/geckoview/features/browser/domain/services/engine_settings_replication.g.dart @@ -44,7 +44,7 @@ final class EngineSettingsReplicationServiceProvider } String _$engineSettingsReplicationServiceHash() => - r'81443c37d18ad82f0694cd0e1115ccdf8a0f4c06'; + r'061f0b32a9c49e3bd4b76cd99993620558e0d3b2'; abstract class _$EngineSettingsReplicationService extends $Notifier { void build(); diff --git a/apps/weblibre/lib/features/settings/presentation/screens/privacy_security_settings.dart b/apps/weblibre/lib/features/settings/presentation/screens/privacy_security_settings.dart index 87d40c80..b6c34f38 100644 --- a/apps/weblibre/lib/features/settings/presentation/screens/privacy_security_settings.dart +++ b/apps/weblibre/lib/features/settings/presentation/screens/privacy_security_settings.dart @@ -55,6 +55,7 @@ class PrivacySecuritySettingsScreen extends StatelessWidget { _NetworkProtectionSection(), _PrivacySignalsSection(), _DataManagementSection(), + _SafeBrowsingSection(), _AdvancedSecuritySection(), ], ); @@ -145,6 +146,21 @@ class _PrivacySignalsSection extends StatelessWidget { } } +class _SafeBrowsingSection extends StatelessWidget { + const _SafeBrowsingSection(); + + @override + Widget build(BuildContext context) { + return const Column( + children: [ + SettingSection(name: 'Google Safe Browsing'), + _SafeBrowsingMalwareTile(), + _SafeBrowsingPhishingTile(), + ], + ); + } +} + class _DataManagementSection extends StatelessWidget { const _DataManagementSection(); @@ -739,6 +755,64 @@ class _FissionEnabledTile extends HookConsumerWidget { } } +class _SafeBrowsingMalwareTile extends HookConsumerWidget { + const _SafeBrowsingMalwareTile(); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final safeBrowsingMalwareEnabled = ref.watch( + engineSettingsWithDefaultsProvider.select( + (s) => s.safeBrowsingMalwareEnabled, + ), + ); + + return SwitchListTile.adaptive( + title: const Text('Safe Browsing Malware Protection'), + subtitle: const Text( + 'Warn about dangerous websites and malicious downloads.', + ), + secondary: const Icon(Icons.bug_report_outlined), + value: safeBrowsingMalwareEnabled, + onChanged: (value) async { + await ref + .read(saveEngineSettingsControllerProvider.notifier) + .save( + (currentSettings) => + currentSettings.copyWith.safeBrowsingMalwareEnabled(value), + ); + }, + ); + } +} + +class _SafeBrowsingPhishingTile extends HookConsumerWidget { + const _SafeBrowsingPhishingTile(); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final safeBrowsingPhishingEnabled = ref.watch( + engineSettingsWithDefaultsProvider.select( + (s) => s.safeBrowsingPhishingEnabled, + ), + ); + + return SwitchListTile.adaptive( + title: const Text('Safe Browsing Phishing Protection'), + subtitle: const Text('Warn about deceptive websites and login pages.'), + secondary: const Icon(Icons.gpp_maybe_outlined), + value: safeBrowsingPhishingEnabled, + onChanged: (value) async { + await ref + .read(saveEngineSettingsControllerProvider.notifier) + .save( + (currentSettings) => + currentSettings.copyWith.safeBrowsingPhishingEnabled(value), + ); + }, + ); + } +} + class _ExtensionsWebAPIEnabledTile extends HookConsumerWidget { const _ExtensionsWebAPIEnabledTile(); diff --git a/apps/weblibre/lib/features/user/data/models/engine_settings.dart b/apps/weblibre/lib/features/user/data/models/engine_settings.dart index 9d9f636b..e3aa201e 100644 --- a/apps/weblibre/lib/features/user/data/models/engine_settings.dart +++ b/apps/weblibre/lib/features/user/data/models/engine_settings.dart @@ -159,6 +159,10 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { final bool enablePdfJs; + final bool safeBrowsingMalwareEnabled; + + final bool safeBrowsingPhishingEnabled; + EngineSettings({ required super.javascriptEnabled, required super.trackingProtectionPolicy, @@ -181,6 +185,8 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { required this.dohExceptionsList, required super.fingerprintingProtectionOverrides, required this.enablePdfJs, + required this.safeBrowsingMalwareEnabled, + required this.safeBrowsingPhishingEnabled, required super.locales, required super.blockCookies, required super.customCookiePolicy, @@ -232,6 +238,8 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { List? dohExceptionsList, String? fingerprintingProtectionOverrides, bool? enablePdfJs, + bool? safeBrowsingMalwareEnabled, + bool? safeBrowsingPhishingEnabled, List? locales, bool? blockCookies, CustomCookiePolicy? customCookiePolicy, @@ -269,6 +277,8 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { dohDefaultProviderUrl ?? BuiltInDohProviders.quad9.url, dohExceptionsList = dohExceptionsList ?? [], enablePdfJs = enablePdfJs ?? true, + safeBrowsingMalwareEnabled = safeBrowsingMalwareEnabled ?? true, + safeBrowsingPhishingEnabled = safeBrowsingPhishingEnabled ?? true, super( javascriptEnabled: javascriptEnabled ?? true, trackingProtectionPolicy: @@ -359,6 +369,8 @@ class EngineSettings extends GeckoEngineSettings with FastEquatable { dohExceptionsList, fingerprintingProtectionOverrides, enablePdfJs, + safeBrowsingMalwareEnabled, + safeBrowsingPhishingEnabled, locales, blockCookies, customCookiePolicy, diff --git a/apps/weblibre/lib/features/user/data/models/engine_settings.g.dart b/apps/weblibre/lib/features/user/data/models/engine_settings.g.dart index 6d826579..eb70ae1a 100644 --- a/apps/weblibre/lib/features/user/data/models/engine_settings.g.dart +++ b/apps/weblibre/lib/features/user/data/models/engine_settings.g.dart @@ -67,6 +67,10 @@ abstract class _$EngineSettingsCWProxy { EngineSettings enablePdfJs(bool enablePdfJs); + EngineSettings safeBrowsingMalwareEnabled(bool safeBrowsingMalwareEnabled); + + EngineSettings safeBrowsingPhishingEnabled(bool safeBrowsingPhishingEnabled); + EngineSettings locales(List? locales); EngineSettings blockCookies(bool? blockCookies); @@ -154,6 +158,8 @@ abstract class _$EngineSettingsCWProxy { List dohExceptionsList, String? fingerprintingProtectionOverrides, bool enablePdfJs, + bool safeBrowsingMalwareEnabled, + bool safeBrowsingPhishingEnabled, List? locales, bool? blockCookies, CustomCookiePolicy? customCookiePolicy, @@ -292,6 +298,15 @@ class _$EngineSettingsCWProxyImpl implements _$EngineSettingsCWProxy { EngineSettings enablePdfJs(bool enablePdfJs) => call(enablePdfJs: enablePdfJs); + @override + EngineSettings safeBrowsingMalwareEnabled(bool safeBrowsingMalwareEnabled) => + call(safeBrowsingMalwareEnabled: safeBrowsingMalwareEnabled); + + @override + EngineSettings safeBrowsingPhishingEnabled( + bool safeBrowsingPhishingEnabled, + ) => call(safeBrowsingPhishingEnabled: safeBrowsingPhishingEnabled); + @override EngineSettings locales(List? locales) => call(locales: locales); @@ -433,6 +448,8 @@ class _$EngineSettingsCWProxyImpl implements _$EngineSettingsCWProxy { Object? dohExceptionsList = const $CopyWithPlaceholder(), Object? fingerprintingProtectionOverrides = const $CopyWithPlaceholder(), Object? enablePdfJs = const $CopyWithPlaceholder(), + Object? safeBrowsingMalwareEnabled = const $CopyWithPlaceholder(), + Object? safeBrowsingPhishingEnabled = const $CopyWithPlaceholder(), Object? locales = const $CopyWithPlaceholder(), Object? blockCookies = const $CopyWithPlaceholder(), Object? customCookiePolicy = const $CopyWithPlaceholder(), @@ -571,6 +588,18 @@ class _$EngineSettingsCWProxyImpl implements _$EngineSettingsCWProxy { ? _value.enablePdfJs // ignore: cast_nullable_to_non_nullable : enablePdfJs as bool, + safeBrowsingMalwareEnabled: + safeBrowsingMalwareEnabled == const $CopyWithPlaceholder() || + safeBrowsingMalwareEnabled == null + ? _value.safeBrowsingMalwareEnabled + // ignore: cast_nullable_to_non_nullable + : safeBrowsingMalwareEnabled as bool, + safeBrowsingPhishingEnabled: + safeBrowsingPhishingEnabled == const $CopyWithPlaceholder() || + safeBrowsingPhishingEnabled == null + ? _value.safeBrowsingPhishingEnabled + // ignore: cast_nullable_to_non_nullable + : safeBrowsingPhishingEnabled as bool, locales: locales == const $CopyWithPlaceholder() ? _value.locales // ignore: cast_nullable_to_non_nullable @@ -760,6 +789,8 @@ EngineSettings _$EngineSettingsFromJson( fingerprintingProtectionOverrides: json['fingerprintingProtectionOverrides'] as String?, enablePdfJs: json['enablePdfJs'] as bool?, + safeBrowsingMalwareEnabled: json['safeBrowsingMalwareEnabled'] as bool?, + safeBrowsingPhishingEnabled: json['safeBrowsingPhishingEnabled'] as bool?, locales: (json['locales'] as List?) ?.map((e) => e as String) .toList(), @@ -867,6 +898,8 @@ Map _$EngineSettingsToJson( 'dohDefaultProviderUrl': instance.dohDefaultProviderUrl, 'dohExceptionsList': instance.dohExceptionsList, 'enablePdfJs': instance.enablePdfJs, + 'safeBrowsingMalwareEnabled': instance.safeBrowsingMalwareEnabled, + 'safeBrowsingPhishingEnabled': instance.safeBrowsingPhishingEnabled, }; const _$TrackingProtectionPolicyEnumMap = { diff --git a/apps/weblibre/lib/features/user/domain/repositories/engine_settings.dart b/apps/weblibre/lib/features/user/domain/repositories/engine_settings.dart index 871fbd8b..91f143b4 100644 --- a/apps/weblibre/lib/features/user/domain/repositories/engine_settings.dart +++ b/apps/weblibre/lib/features/user/domain/repositories/engine_settings.dart @@ -124,6 +124,10 @@ class EngineSettingsRepository extends _$EngineSettingsRepository { DriftSqlType.bool, db.typeMapping, ), + 'safeBrowsingMalwareEnabled': settings['safeBrowsingMalwareEnabled'] + ?.readAs(DriftSqlType.bool, db.typeMapping), + 'safeBrowsingPhishingEnabled': settings['safeBrowsingPhishingEnabled'] + ?.readAs(DriftSqlType.bool, db.typeMapping), 'locales': settings['locales'] ?.readAs(DriftSqlType.string, db.typeMapping) .mapNotNull(jsonDecode), diff --git a/apps/weblibre/lib/features/user/domain/repositories/engine_settings.g.dart b/apps/weblibre/lib/features/user/domain/repositories/engine_settings.g.dart index 165c466f..ae6db78b 100644 --- a/apps/weblibre/lib/features/user/domain/repositories/engine_settings.g.dart +++ b/apps/weblibre/lib/features/user/domain/repositories/engine_settings.g.dart @@ -34,7 +34,7 @@ final class EngineSettingsRepositoryProvider } String _$engineSettingsRepositoryHash() => - r'4abe41cfeba8e39484683033f11c54be644fa2b2'; + r'f3fe745e37ec89c2d403906250aea66321c3e505'; abstract class _$EngineSettingsRepository extends $StreamNotifier {