don't require requireBuiltInCerts when installing unsigned extensions

This commit is contained in:
Fabian Freund
2026-03-20 05:03:43 +01:00
parent df55e9e8af
commit 64d320cf05
2 changed files with 32 additions and 4 deletions
@@ -29,6 +29,9 @@ import 'package:weblibre/features/geckoview/domain/providers.dart';
part 'browser_addon.g.dart';
const _signatureRequiredPref = 'xpinstall.signatures.required';
const _installRequireBuiltInCertsPref =
'extensions.install.requireBuiltInCerts';
const _updateRequireBuiltInCertsPref = 'extensions.update.requireBuiltInCerts';
@Riverpod(keepAlive: true)
class BrowserAddonService extends _$BrowserAddonService {
@@ -73,6 +76,13 @@ class BrowserAddonService extends _$BrowserAddonService {
bool allowUnsigned = false,
}) async {
final prefService = GeckoPrefService();
final unsignedInstallPrefs = {
_signatureRequiredPref: false,
_installRequireBuiltInCertsPref: false,
_updateRequireBuiltInCertsPref: false,
};
Map<String, Object>? previousUnsignedInstallPrefs;
try {
// Validate file exists and has .xpi extension
@@ -88,7 +98,25 @@ class BrowserAddonService extends _$BrowserAddonService {
// Temporarily disable signature requirement if user allows unsigned
if (allowUnsigned) {
await prefService.applyPrefs({_signatureRequiredPref: false});
final existingPrefs = await prefService.getPrefs(
unsignedInstallPrefs.keys.toList(),
);
previousUnsignedInstallPrefs = {
for (final entry in existingPrefs.entries)
if (entry.value.value case final Object value) entry.key: value,
};
await prefService.applyPrefs(unsignedInstallPrefs);
final appliedPrefs = await prefService.getPrefs(
unsignedInstallPrefs.keys.toList(),
);
logger.i(
'Prepared unsigned add-on install prefs: '
'${appliedPrefs.map((key, value) => MapEntry(key, value.value))}',
);
}
try {
@@ -101,8 +129,8 @@ class BrowserAddonService extends _$BrowserAddonService {
return true;
} finally {
// Always restore signature requirement
if (allowUnsigned) {
await prefService.applyPrefs({_signatureRequiredPref: true});
if (allowUnsigned && previousUnsignedInstallPrefs != null) {
await prefService.applyPrefs(previousUnsignedInstallPrefs);
}
}
} catch (e, s) {
@@ -88,7 +88,7 @@ class _InstallLocalAddonSheet extends HookConsumerWidget {
if (errorString.contains('NotSigned') ||
errorString.contains('SIGNEDSTATE')) {
errorMessage.value =
'This extension is not signed by Mozilla. Enable "Allow unsigned extensions" to install it.';
'This extension is not signed by Mozilla. Enable "Allow unsigned extensions" to retry.';
} else {
errorMessage.value = 'Installation failed: $errorString';
}