Skip to content

Commit

Permalink
Merge pull request #680 from ThexXTURBOXx/develop
Browse files Browse the repository at this point in the history
Update js dependency and migrate to web
  • Loading branch information
juliansteenbakker committed May 8, 2024
2 parents bf74b32 + d17d52a commit 7e2321a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 24 deletions.
4 changes: 4 additions & 0 deletions flutter_secure_storage_web/CHANGELOG.md
@@ -1,3 +1,7 @@
## 1.2.0
- Migrate away from `html` to `web`
- Allow newer `js` versions to be used with this package

## 1.1.2
- Update Dart SDK Constraint to support <4.0.0 instead of <3.0.0.

Expand Down
46 changes: 25 additions & 21 deletions flutter_secure_storage_web/lib/flutter_secure_storage_web.dart
Expand Up @@ -2,13 +2,15 @@
library flutter_secure_storage_web;

import 'dart:convert';
import 'dart:html' as html;
import 'dart:js_interop';
import 'dart:js_interop_unsafe';
import 'dart:js_util' as js_util;
import 'dart:typed_data';

import 'package:flutter_secure_storage_platform_interface/flutter_secure_storage_platform_interface.dart';
import 'package:flutter_secure_storage_web/src/subtle.dart' as crypto;
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:web/web.dart';

/// Web implementation of FlutterSecureStorage
class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
Expand All @@ -26,7 +28,7 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
required Map<String, String> options,
}) =>
Future.value(
html.window.localStorage.containsKey("${options[_publicKey]!}.$key"),
window.localStorage.has("${options[_publicKey]!}.$key"),
);

/// Deletes associated value for the given [key].
Expand All @@ -37,7 +39,7 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
required String key,
required Map<String, String> options,
}) async {
html.window.localStorage.remove("${options[_publicKey]!}.$key");
window.localStorage.removeItem("${options[_publicKey]!}.$key");
}

/// Deletes all keys with associated values.
Expand All @@ -46,7 +48,7 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
required Map<String, String> options,
}) =>
Future.sync(
() => html.window.localStorage.removeWhere((key, value) => true),
() => window.localStorage.clear(),
);

/// Encrypts and saves the [key] with the given [value].
Expand All @@ -58,7 +60,7 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
required String key,
required Map<String, String> options,
}) async {
final value = html.window.localStorage["${options[_publicKey]!}.$key"];
final value = window.localStorage["${options[_publicKey]!}.$key"];

return _decryptValue(value, options);
}
Expand All @@ -70,19 +72,19 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
}) async {
final map = <String, String>{};
final prefix = "${options[_publicKey]!}.";
for (int j = 0; j < html.window.localStorage.length; j++) {
final entry = html.window.localStorage.entries.elementAt(j);
if (!entry.key.startsWith(prefix)) {
for (int j = 0; j < window.localStorage.length; j++) {
final key = window.localStorage.key(j) ?? '';
if (!key.startsWith(prefix)) {
continue;
}

final value = await _decryptValue(entry.value, options);
final value = await _decryptValue(window.localStorage[key], options);

if (value == null) {
continue;
}

map[entry.key.substring(prefix.length)] = value;
map[key.substring(prefix.length)] = value;
}

return map;
Expand All @@ -91,29 +93,29 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
crypto.Algorithm _getAlgorithm(Uint8List iv) =>
crypto.Algorithm(name: 'AES-GCM', length: 256, iv: iv);

Future<html.CryptoKey> _getEncryptionKey(
Future<CryptoKey> _getEncryptionKey(
crypto.Algorithm algorithm,
Map<String, String> options,
) async {
late html.CryptoKey encryptionKey;
late CryptoKey encryptionKey;
final key = options[_publicKey]!;

if (html.window.localStorage.containsKey(key)) {
final jwk = base64Decode(html.window.localStorage[key]!);
if (window.localStorage.has(key)) {
final jwk = base64Decode(window.localStorage[key]!);

encryptionKey = await js_util.promiseToFuture<html.CryptoKey>(
encryptionKey = await js_util.promiseToFuture<CryptoKey>(
crypto.importKey("raw", jwk, algorithm, false, ["encrypt", "decrypt"]),
);
} else {
//final crypto.getRandomValues(Uint8List(256));

encryptionKey = await js_util.promiseToFuture<html.CryptoKey>(
encryptionKey = await js_util.promiseToFuture<CryptoKey>(
crypto.generateKey(algorithm, true, ["encrypt", "decrypt"]),
);

final jsonWebKey = await js_util
.promiseToFuture<ByteBuffer>(crypto.exportKey("raw", encryptionKey));
html.window.localStorage[key] = base64Encode(jsonWebKey.asUint8List());
window.localStorage[key] = base64Encode(jsonWebKey.asUint8List());
}

return encryptionKey;
Expand All @@ -129,8 +131,10 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
required String value,
required Map<String, String> options,
}) async {
final iv =
html.window.crypto!.getRandomValues(Uint8List(12)).buffer.asUint8List();
final iv = (window.crypto.getRandomValues(Uint8List(12).toJS).dartify()!
as Uint8List)
.buffer
.asUint8List();

final algorithm = _getAlgorithm(iv);

Expand All @@ -149,7 +153,7 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {
final encoded =
"${base64Encode(iv)}.${base64Encode(encryptedContent.asUint8List())}";

html.window.localStorage["${options[_publicKey]!}.$key"] = encoded;
window.localStorage["${options[_publicKey]!}.$key"] = encoded;
}

Future<String?> _decryptValue(
Expand Down Expand Up @@ -187,5 +191,5 @@ class FlutterSecureStorageWeb extends FlutterSecureStoragePlatform {

@override
Stream<bool> get onCupertinoProtectedDataAvailabilityChanged =>
Stream.empty();
const Stream.empty();
}
2 changes: 1 addition & 1 deletion flutter_secure_storage_web/lib/src/subtle.dart
Expand Up @@ -18,12 +18,12 @@
library common;

import 'dart:convert' show jsonDecode;
import 'dart:html';
import 'dart:js_util' as js_util;
import 'dart:typed_data';

import 'package:flutter_secure_storage_web/src/jsonwebkey.dart' show JsonWebKey;
import 'package:js/js.dart';
import 'package:web/web.dart' hide JsonWebKey;

export 'jsonwebkey.dart' show JsonWebKey;

Expand Down
5 changes: 3 additions & 2 deletions flutter_secure_storage_web/pubspec.yaml
@@ -1,7 +1,7 @@
name: flutter_secure_storage_web
description: Web implementation of flutter_secure_storage. Use flutter_secure_storage for the full flutter package.
repository: https://github.com/mogol/flutter_secure_storage
version: 1.1.2
version: 1.2.0

environment:
sdk: ">=2.12.0 <4.0.0"
Expand All @@ -13,7 +13,8 @@ dependencies:
flutter_secure_storage_platform_interface: ^1.0.1
flutter_web_plugins:
sdk: flutter
js: ^0.6.3
js: '>=0.6.3 <1.0.0'
web: '>=0.5.0 <1.0.0'

dev_dependencies:
lint: ^2.0.0
Expand Down

0 comments on commit 7e2321a

Please sign in to comment.