diff --git a/lib/solidpod.dart b/lib/solidpod.dart index d0650306..4b4c8834 100644 --- a/lib/solidpod.dart +++ b/lib/solidpod.dart @@ -116,7 +116,8 @@ export 'src/solid/utils/misc.dart' isDir, logoutPod, registerLogoutCacheCallback, - setAppDirName; + setAppDirName, + silentLogout; /// Helper for deleting files and containers from a Solid POD diff --git a/lib/src/solid/utils/misc.dart b/lib/src/solid/utils/misc.dart index b92c21bc..06f1fbf4 100644 --- a/lib/src/solid/utils/misc.dart +++ b/lib/src/solid/utils/misc.dart @@ -34,6 +34,7 @@ import 'package:flutter/foundation.dart' show debugPrint; import 'package:encrypter_plus/encrypter_plus.dart'; import 'package:fast_rsa/fast_rsa.dart' show KeyPair; +import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; import 'package:jwt_decoder/jwt_decoder.dart'; import 'package:path/path.dart' as path; @@ -518,6 +519,49 @@ Future logoutPod() async { } } +/// Clear all login state without opening a browser. +/// +/// Performs the same cleanup as [logoutPod] but invalidates the IdP session +/// via a headless HTTP request rather than launching a visible browser +/// window. Use this when switching accounts or recovering from stale +/// credentials. + +Future silentLogout() async { + try { + await KeyManager.clear(); + + final logoutUrl = await AuthDataManager.getLogoutUrl(); + final authDataRemoved = await AuthDataManager.removeAuthData(); + + if (_onLogoutClearCaches != null) { + try { + await _onLogoutClearCaches!(); + } on Object catch (e) { + debugPrint('silentLogout() cache callback failed (non-critical): $e'); + } + } + + // Best-effort IdP session invalidation via headless HTTP GET. + + if (logoutUrl != null && logoutUrl.isNotEmpty) { + try { + await http.get(Uri.parse(logoutUrl)); + } on Object catch (e) { + debugPrint('silentLogout() headless logout failed (non-critical): $e'); + } + } + + return authDataRemoved; + } on Object catch (e) { + debugPrint('silentLogout() CRITICAL: $e'); + try { + await AuthDataManager.removeAuthData(); + await KeyManager.clear(); + } on Object catch (_) {} + return false; + } +} + /// Removes header and footer (which mess up the TTL format) from a PEM-formatted public key string. /// /// This function takes a public key string, typically in PEM format, and removes