diff --git a/.github/workflows/celest_core.yaml b/.github/workflows/celest_core.yaml index 1d748201..ca216f7c 100644 --- a/.github/workflows/celest_core.yaml +++ b/.github/workflows/celest_core.yaml @@ -151,3 +151,23 @@ jobs: # - name: Test (Windows) # working-directory: packages/celest_core/example # run: flutter test -d windows integration_test/secure_storage_test.dart + test_web: + needs: analyze_and_format + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Git Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # 4.1.1 + - name: Setup Flutter + uses: subosito/flutter-action@62f096cacda5168a3bd7b95793373be14fa4fbaf # 2.13.0 + with: + cache: true + - name: Get Packages + working-directory: packages/celest_core + run: dart pub get + - name: Test (Chrome, dart2js) + working-directory: packages/celest_core + run: dart test -p chrome + - name: Test (Chrome, dart2wasm) + working-directory: packages/celest_core + run: dart test -p chrome -c dart2wasm diff --git a/packages/celest_core/lib/src/secure_storage/secure_storage.dart b/packages/celest_core/lib/src/secure_storage/secure_storage.dart index e90ac9bb..c41def08 100644 --- a/packages/celest_core/lib/src/secure_storage/secure_storage.dart +++ b/packages/celest_core/lib/src/secure_storage/secure_storage.dart @@ -9,3 +9,25 @@ abstract interface class SecureStorage { String? delete(String key); void clear(); } + +/// An in-memory implementation of [SecureStorage]. +final class MemorySecureStorage implements SecureStorage { + MemorySecureStorage({ + required this.scope, + }); + + final _storage = {}; + final String scope; + + @override + void clear() => _storage.removeWhere((key, _) => key.startsWith('$scope/')); + + @override + String? delete(String key) => _storage.remove('$scope/$key'); + + @override + String? read(String key) => _storage['$scope/$key']; + + @override + String write(String key, String value) => _storage['$scope/$key'] = value; +} diff --git a/packages/celest_core/lib/src/secure_storage/secure_storage.stub.dart b/packages/celest_core/lib/src/secure_storage/secure_storage.stub.dart deleted file mode 100644 index 856f05c9..00000000 --- a/packages/celest_core/lib/src/secure_storage/secure_storage.stub.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:celest_core/src/secure_storage/secure_storage_platform.web.dart'; - -/// An in-memory implementation of [SecureStoragePlatform] for platforms which -/// do not support secure storage. -final class SecureStoragePlatformStub extends SecureStoragePlatform { - SecureStoragePlatformStub({ - required this.scope, - }) : super.base(); - - final _storage = {}; - final String scope; - - @override - void clear() => _storage.removeWhere((key, _) => key.startsWith('$scope:')); - - @override - String? delete(String key) => _storage.remove('$scope:$key'); - - @override - String? read(String key) => _storage['$scope:$key']; - - @override - String write(String key, String value) => _storage['$scope:$key'] = value; -} diff --git a/packages/celest_core/lib/src/secure_storage/secure_storage_platform.web.dart b/packages/celest_core/lib/src/secure_storage/secure_storage_platform.web.dart index a657e936..ac4dcc10 100644 --- a/packages/celest_core/lib/src/secure_storage/secure_storage_platform.web.dart +++ b/packages/celest_core/lib/src/secure_storage/secure_storage_platform.web.dart @@ -1,15 +1,42 @@ import 'package:celest_core/src/secure_storage/secure_storage.dart'; -import 'package:celest_core/src/secure_storage/secure_storage.stub.dart'; -import 'package:meta/meta.dart'; +import 'package:web/web.dart' as web; -abstract base class SecureStoragePlatform implements SecureStorage { - factory SecureStoragePlatform({ +final class SecureStoragePlatform implements SecureStorage { + SecureStoragePlatform({ String? scope, - }) => - SecureStoragePlatformStub(scope: scope ?? _defaultScope); + }) : scope = scope ?? _defaultScope; + + final String scope; static const _defaultScope = 'dev.celest.celest'; - @protected - const SecureStoragePlatform.base(); + List get _keys => [ + for (var i = 0; i < web.window.localStorage.length; i++) + web.window.localStorage.key(i)!, + ]; + + @override + void clear() { + for (final key in _keys) { + if (key.startsWith('$scope/')) { + web.window.localStorage.removeItem(key); + } + } + } + + @override + String? delete(String key) { + final value = read(key); + web.window.localStorage.removeItem('$scope/$key'); + return value; + } + + @override + String? read(String key) => web.window.localStorage.getItem('$scope/$key'); + + @override + String write(String key, String value) { + web.window.localStorage.setItem('$scope/$key', value); + return value; + } } diff --git a/packages/celest_core/pubspec.yaml b/packages/celest_core/pubspec.yaml index 009693fe..a9db7617 100644 --- a/packages/celest_core/pubspec.yaml +++ b/packages/celest_core/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: meta: ^1.10.0 os_detect: ^2.0.1 path: ^1.9.0 + web: ^0.5.1 win32: ^5.2.0 dev_dependencies: