From ce9de9f7d6d6856f45475e5a4feefc04d26c0e73 Mon Sep 17 00:00:00 2001 From: Williams Date: Tue, 9 Dec 2025 18:34:44 +1100 Subject: [PATCH 1/8] new --- lib/solid_auth_client.dart | 11 +++++++++++ lib/src/auth_manager/auth_manager_abstract.dart | 1 + lib/src/auth_manager/web_auth_manager.dart | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/lib/solid_auth_client.dart b/lib/solid_auth_client.dart index 9dd8a06..5df15d0 100644 --- a/lib/solid_auth_client.dart +++ b/lib/solid_auth_client.dart @@ -321,6 +321,17 @@ Future authenticate( } Future logout(logoutUrl) async { + // Step 1: Clear web platform local storage before logout redirect + if (currPlatform.isWeb()) { + try { + authManager.clearLocalStorage(); + debugPrint('logout() => Web localStorage cleared successfully'); + } catch (e) { + debugPrint('logout() => Warning: Failed to clear localStorage: $e'); + // Continue anyway - the important part is clearing auth data + } + } + Uri url = Uri.parse(logoutUrl); if (await canLaunchUrl(url)) { diff --git a/lib/src/auth_manager/auth_manager_abstract.dart b/lib/src/auth_manager/auth_manager_abstract.dart index d880fb9..144394e 100644 --- a/lib/src/auth_manager/auth_manager_abstract.dart +++ b/lib/src/auth_manager/auth_manager_abstract.dart @@ -44,6 +44,7 @@ abstract class AuthManager { createAuthenticator(Client client, List scopes, String dPopToken) {} getOidcWeb() {} userLogout(String logoutUrl) {} + clearLocalStorage() {} // factory constructor to return the correct implementation. factory AuthManager() => getAuthManager(); diff --git a/lib/src/auth_manager/web_auth_manager.dart b/lib/src/auth_manager/web_auth_manager.dart index f48d3b2..1186cdf 100644 --- a/lib/src/auth_manager/web_auth_manager.dart +++ b/lib/src/auth_manager/web_auth_manager.dart @@ -80,6 +80,15 @@ class WebAuthManager implements AuthManager { final child = window.open(logoutUrl, 'user_logout'); child!.close(); } + + @override + clearLocalStorage() { + try { + windowLoc.localStorage.clear(); + } catch (e) { + throw 'Failed to clear localStorage: $e'; + } + } } AuthManager getAuthManager() => WebAuthManager(); From 889677b48121ac24cdd2481f435ebb1600c7117e Mon Sep 17 00:00:00 2001 From: Williams Date: Tue, 9 Dec 2025 20:16:28 +1100 Subject: [PATCH 2/8] new --- lib/solid_auth_client.dart | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/solid_auth_client.dart b/lib/solid_auth_client.dart index 5df15d0..b36b0af 100644 --- a/lib/solid_auth_client.dart +++ b/lib/solid_auth_client.dart @@ -31,7 +31,9 @@ library; import 'dart:async'; import 'dart:convert'; +import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/widgets.dart'; +import 'package:web/web.dart' as web; import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; import 'package:fast_rsa/fast_rsa.dart'; @@ -162,6 +164,16 @@ Future authenticate( List scopes, BuildContext context, ) async { + // On Web platform, immediately reload the page when authentication is triggered + // This ensures guest users see a fresh login screen + if (kIsWeb) { + await Future.delayed(const Duration(milliseconds: 50)); + // Use conditional import for web reload + _reloadPageIfWeb(); + // Code after reload won't execute, but return empty map just in case + return {}; + } + /// Platform type parameter String platformType; @@ -350,3 +362,10 @@ Future logout(logoutUrl) async { } return true; } + +/// Helper function to reload page on web platform +void _reloadPageIfWeb() { + if (kIsWeb) { + web.window.location.reload(); + } +} From a518ea2c9f9b209483de61e77984c6e3b4253548 Mon Sep 17 00:00:00 2001 From: Williams Date: Tue, 9 Dec 2025 22:46:58 +1100 Subject: [PATCH 3/8] new --- lib/solid_auth_client.dart | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/lib/solid_auth_client.dart b/lib/solid_auth_client.dart index b36b0af..5df15d0 100644 --- a/lib/solid_auth_client.dart +++ b/lib/solid_auth_client.dart @@ -31,9 +31,7 @@ library; import 'dart:async'; import 'dart:convert'; -import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/widgets.dart'; -import 'package:web/web.dart' as web; import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; import 'package:fast_rsa/fast_rsa.dart'; @@ -164,16 +162,6 @@ Future authenticate( List scopes, BuildContext context, ) async { - // On Web platform, immediately reload the page when authentication is triggered - // This ensures guest users see a fresh login screen - if (kIsWeb) { - await Future.delayed(const Duration(milliseconds: 50)); - // Use conditional import for web reload - _reloadPageIfWeb(); - // Code after reload won't execute, but return empty map just in case - return {}; - } - /// Platform type parameter String platformType; @@ -362,10 +350,3 @@ Future logout(logoutUrl) async { } return true; } - -/// Helper function to reload page on web platform -void _reloadPageIfWeb() { - if (kIsWeb) { - web.window.location.reload(); - } -} From 8bbd9ae8205093e71bada7a6375856d280648edc Mon Sep 17 00:00:00 2001 From: Williams Date: Sat, 13 Dec 2025 13:14:35 +1100 Subject: [PATCH 4/8] new --- lib/solid_auth_client.dart | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/solid_auth_client.dart b/lib/solid_auth_client.dart index 5df15d0..28f5d8d 100644 --- a/lib/solid_auth_client.dart +++ b/lib/solid_auth_client.dart @@ -178,10 +178,12 @@ Future authenticate( /// Output data from the authentication Map authData; - /// Check the platform - if (currPlatform.isWeb()) { + /// Check the platform using PlatformInfo + final platformTypeEnum = currPlatform.getCurrentPlatformType(); + if (platformTypeEnum == PlatformType.web) { platformType = 'web'; - } else if (currPlatform.isAppOS()) { + } else if (platformTypeEnum == PlatformType.iOS || + platformTypeEnum == PlatformType.android) { platformType = 'mobile'; } else { platformType = 'desktop'; @@ -321,15 +323,12 @@ Future authenticate( } Future logout(logoutUrl) async { - // Step 1: Clear web platform local storage before logout redirect - if (currPlatform.isWeb()) { - try { - authManager.clearLocalStorage(); - debugPrint('logout() => Web localStorage cleared successfully'); - } catch (e) { - debugPrint('logout() => Warning: Failed to clear localStorage: $e'); - // Continue anyway - the important part is clearing auth data - } + // Clear platform-specific storage (Web: localStorage, others: no-op) + try { + authManager.clearLocalStorage(); + } catch (e) { + debugPrint('logout() => Warning: Failed to clear storage: $e'); + // Continue anyway - the important part is clearing auth data } Uri url = Uri.parse(logoutUrl); From 068440f645884d11ecca19c12f23a28d08c48427 Mon Sep 17 00:00:00 2001 From: Williams Date: Sun, 14 Dec 2025 10:58:20 +1100 Subject: [PATCH 5/8] new --- lib/solid_auth_client.dart | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/solid_auth_client.dart b/lib/solid_auth_client.dart index 28f5d8d..bff0a78 100644 --- a/lib/solid_auth_client.dart +++ b/lib/solid_auth_client.dart @@ -178,12 +178,10 @@ Future authenticate( /// Output data from the authentication Map authData; - /// Check the platform using PlatformInfo - final platformTypeEnum = currPlatform.getCurrentPlatformType(); - if (platformTypeEnum == PlatformType.web) { + /// Check the platform + if (currPlatform.isWeb()) { platformType = 'web'; - } else if (platformTypeEnum == PlatformType.iOS || - platformTypeEnum == PlatformType.android) { + } else if (currPlatform.isAppOS()) { platformType = 'mobile'; } else { platformType = 'desktop'; From dc23168147169b40d18517bd0c1de96283e1dd33 Mon Sep 17 00:00:00 2001 From: Williams Date: Wed, 17 Dec 2025 02:36:04 +1100 Subject: [PATCH 6/8] new --- example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index d25d712..fb7ba42 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -19,4 +19,4 @@ dependencies: flutter: assets: - assets/images/ - uses-material-design: true + uses-material-design: true \ No newline at end of file From 8f9a36f9f425ecedfb00304ebf9c37940762cb9d Mon Sep 17 00:00:00 2001 From: Williams Date: Fri, 19 Dec 2025 20:42:40 +1100 Subject: [PATCH 7/8] new --- LICENSE | 2 +- example/pubspec.yaml | 2 +- example/web/callback.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE b/LICENSE index 01b4308..a60ace9 100644 --- a/LICENSE +++ b/LICENSE @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/example/pubspec.yaml b/example/pubspec.yaml index fb7ba42..d25d712 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -19,4 +19,4 @@ dependencies: flutter: assets: - assets/images/ - uses-material-design: true \ No newline at end of file + uses-material-design: true diff --git a/example/web/callback.html b/example/web/callback.html index 5738d63..a5a3d50 100644 --- a/example/web/callback.html +++ b/example/web/callback.html @@ -27,4 +27,4 @@ - \ No newline at end of file + From c504c94994e1a69d64d0a0866e8c9855fba5376e Mon Sep 17 00:00:00 2001 From: Williams Date: Wed, 7 Jan 2026 20:09:51 +1100 Subject: [PATCH 8/8] clear_sharedpreferences --- lib/solid_auth_client.dart | 6 +- .../auth_manager/auth_manager_abstract.dart | 2 +- lib/src/auth_manager/auth_manager_stub.dart | 5 +- lib/src/auth_manager/native_auth_manager.dart | 79 +++++++++++++++++++ lib/src/auth_manager/web_auth_manager.dart | 4 +- pubspec.yaml | 1 + 6 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 lib/src/auth_manager/native_auth_manager.dart diff --git a/lib/solid_auth_client.dart b/lib/solid_auth_client.dart index 772dfde..aa021c4 100644 --- a/lib/solid_auth_client.dart +++ b/lib/solid_auth_client.dart @@ -321,12 +321,12 @@ Future authenticate( } Future logout(logoutUrl) async { - // Clear platform-specific storage (Web: localStorage, others: no-op) + // Clear platform-specific storage (Web: localStorage, Native: SharedPreferences) try { - authManager.clearLocalStorage(); + await authManager.clearLocalStorage(); } catch (e) { debugPrint('logout() => Warning: Failed to clear storage: $e'); - // Continue anyway - the important part is clearing auth data + // Continue with logout flow even if storage clearing fails } Uri url = Uri.parse(logoutUrl); diff --git a/lib/src/auth_manager/auth_manager_abstract.dart b/lib/src/auth_manager/auth_manager_abstract.dart index 144394e..db964bd 100644 --- a/lib/src/auth_manager/auth_manager_abstract.dart +++ b/lib/src/auth_manager/auth_manager_abstract.dart @@ -44,7 +44,7 @@ abstract class AuthManager { createAuthenticator(Client client, List scopes, String dPopToken) {} getOidcWeb() {} userLogout(String logoutUrl) {} - clearLocalStorage() {} + Future clearLocalStorage() async {} // factory constructor to return the correct implementation. factory AuthManager() => getAuthManager(); diff --git a/lib/src/auth_manager/auth_manager_stub.dart b/lib/src/auth_manager/auth_manager_stub.dart index 1f25ffc..6c64e33 100644 --- a/lib/src/auth_manager/auth_manager_stub.dart +++ b/lib/src/auth_manager/auth_manager_stub.dart @@ -28,7 +28,6 @@ library; import 'package:solid_auth/src/auth_manager/auth_manager_abstract.dart'; +import 'package:solid_auth/src/auth_manager/native_auth_manager.dart'; -AuthManager getAuthManager() => throw UnsupportedError( - 'Cannot create a keyfinder without the packages dart:html or package:shared_preferences', - ); +AuthManager getAuthManager() => NativeAuthManager(); diff --git a/lib/src/auth_manager/native_auth_manager.dart b/lib/src/auth_manager/native_auth_manager.dart new file mode 100644 index 0000000..580706f --- /dev/null +++ b/lib/src/auth_manager/native_auth_manager.dart @@ -0,0 +1,79 @@ +/// Native Auth Manager for non-web platforms. +/// +/// Copyright (C) 2025, Software Innovation Institute, ANU. +/// +/// Licensed under the MIT License (the "License"). +/// +/// License: https://choosealicense.com/licenses/mit/. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +/// +/// Authors: Anushka Vidanage +library; + +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:solid_auth/src/auth_manager/auth_manager_abstract.dart'; +import 'package:solid_auth/src/openid/src/openid.dart'; + +/// Auth manager implementation for native platforms (Linux, Windows, macOS, iOS, Android). +/// +/// This provides platform-specific implementations using SharedPreferences +/// for storage operations on native platforms. +class NativeAuthManager implements AuthManager { + @override + String getKeyValue(String key) { + // Native platforms don't use localStorage + return ''; + } + + @override + getWebUrl() { + // Not applicable for native platforms + return null; + } + + @override + createAuthenticator(Client client, List scopes, String dPopToken) { + // Not applicable for native platforms + return null; + } + + @override + getOidcWeb() { + // Not applicable for native platforms + return null; + } + + @override + userLogout(String logoutUrl) { + // Native platforms handle logout through URL launcher, not window.open + } + + @override + Future clearLocalStorage() async { + try { + final prefs = await SharedPreferences.getInstance(); + await prefs.clear(); + } catch (e) { + throw Exception('Failed to clear SharedPreferences: $e'); + } + } +} + +AuthManager getAuthManager() => NativeAuthManager(); diff --git a/lib/src/auth_manager/web_auth_manager.dart b/lib/src/auth_manager/web_auth_manager.dart index 1186cdf..88065ad 100644 --- a/lib/src/auth_manager/web_auth_manager.dart +++ b/lib/src/auth_manager/web_auth_manager.dart @@ -82,11 +82,11 @@ class WebAuthManager implements AuthManager { } @override - clearLocalStorage() { + Future clearLocalStorage() async { try { windowLoc.localStorage.clear(); } catch (e) { - throw 'Failed to clear localStorage: $e'; + throw Exception('Failed to clear localStorage: $e'); } } } diff --git a/pubspec.yaml b/pubspec.yaml index 6619c39..ad179b5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: url_launcher: ^6.3.1 uuid: ^4.5.1 web: ^1.1.1 + shared_preferences: ^2.2.2 dev_dependencies: flutter_lints: ^5.0.0