Files
sharedinbox/lib/core/services/managesieve_probe_service.dart
T

87 lines
2.6 KiB
Dart

import 'package:sharedinbox/core/models/account.dart';
import 'package:sharedinbox/core/repositories/account_repository.dart';
import 'package:sharedinbox/core/utils/logger.dart';
import 'package:sharedinbox/data/imap/managesieve_client.dart';
/// Returns true if the endpoint accepts a ManageSieve handshake.
typedef ManageSieveProbeFn = Future<bool> Function({
required String host,
required int port,
required bool useTls,
});
Future<bool> _defaultManageSieveProbe({
required String host,
required int port,
required bool useTls,
}) async {
try {
final client = await ManageSieveClient.connect(
host: host,
port: port,
useTls: useTls,
);
try {
await client.logout();
} catch (_) {
/* best-effort */
}
return true;
} catch (e) {
log('ManageSieve probe failed for $host:$port$e');
return false;
}
}
/// Probes whether [account]'s configured ManageSieve endpoint accepts a TCP
/// + STARTTLS handshake, and persists the result on the account row.
///
/// Runs after account add / edit so the IMAP/SMTP form can omit Sieve fields
/// for the common case (port 4190 on the IMAP host). The result drives whether
/// the "Email filters" menu item is shown for this account.
class ManageSieveProbeService {
ManageSieveProbeService(
this._accounts, {
ManageSieveProbeFn probeFn = _defaultManageSieveProbe,
}) : _probeFn = probeFn;
final AccountRepository _accounts;
final ManageSieveProbeFn _probeFn;
Future<void> probe(Account account) async {
if (account.type != AccountType.imap) return;
final host = account.manageSieveHost.trim().isNotEmpty
? account.manageSieveHost.trim()
: account.imapHost;
if (host.isEmpty) return;
final available = await _probeFn(
host: host,
port: account.manageSievePort,
useTls: account.manageSieveSsl,
);
if (account.manageSieveAvailable == available) return;
final updated = _withAvailability(account, available);
await _accounts.updateAccount(updated);
}
Account _withAvailability(Account a, bool available) => Account(
id: a.id,
displayName: a.displayName,
email: a.email,
username: a.username,
type: a.type,
imapHost: a.imapHost,
imapPort: a.imapPort,
imapSsl: a.imapSsl,
smtpHost: a.smtpHost,
smtpPort: a.smtpPort,
smtpSsl: a.smtpSsl,
manageSieveHost: a.manageSieveHost,
manageSievePort: a.manageSievePort,
manageSieveSsl: a.manageSieveSsl,
manageSieveAvailable: available,
jmapUrl: a.jmapUrl,
verbose: a.verbose,
);
}