diff --git a/.github/workflows/chrome.workflow.yml b/.github/workflows/chrome.workflow.yml index 4e5bbafd..d7162520 100644 --- a/.github/workflows/chrome.workflow.yml +++ b/.github/workflows/chrome.workflow.yml @@ -37,4 +37,4 @@ jobs: run: dart pub get - name: Test chrome - run: dart test -j 1 -p chrome + run: dart test --timeout 2x -j 1 -p chrome diff --git a/lib/src/platform_check/node_crypto.dart b/lib/src/platform_check/node_crypto.dart index 5f798a87..3d20b24d 100644 --- a/lib/src/platform_check/node_crypto.dart +++ b/lib/src/platform_check/node_crypto.dart @@ -1,17 +1,43 @@ /// Wrapper for needed NodeJS Crypto library function and require. -library nodecryto; +library nodecrypto; import 'dart:js_interop'; -import 'dart:js_interop_unsafe'; + +const bool isDart2JS = bool.fromEnvironment('dart.tool.dart2js'); + +@JS() +@staticInterop +class Process {} @JS() -external JSObject require(String id); +@staticInterop +class Versions {} + +@JS('process') +external Process? get _process; + +extension on Process { + external Versions? get versions; +} + +extension on Versions { + external JSAny get node; +} + +bool get isNodeDart2JS => _process?.versions?.node != null && isDart2JS; @JS() @staticInterop +class Crypto {} + +extension on Crypto { + external JSUint8Array randomBytes(int size); +} + +@JS() +external Crypto require(String id); + class NodeCrypto { - static JSAny randomFillSync(JSAny buf) { - final crypto = require('crypto'); - return crypto.callMethod('randomFillSync'.toJS, buf); - } + static JSUint8Array randomBytes(int size) => + require('crypto').randomBytes(size); } diff --git a/lib/src/platform_check/web.dart b/lib/src/platform_check/web.dart index 59ef673f..a331d49a 100644 --- a/lib/src/platform_check/web.dart +++ b/lib/src/platform_check/web.dart @@ -10,16 +10,9 @@ import 'platform_check.dart'; class PlatformWeb extends Platform { static final PlatformWeb instance = PlatformWeb(); - static bool useBuiltInRng = false; + static bool useBuiltInRng = !isNodeDart2JS; - PlatformWeb() { - try { - Random.secure(); - useBuiltInRng = true; - } on UnsupportedError { - useBuiltInRng = false; - } - } + const PlatformWeb(); @override bool get isNative => false; @@ -28,17 +21,8 @@ class PlatformWeb extends Platform { String get platform => 'web'; @override - EntropySource platformEntropySource() { - if (useBuiltInRng) { - return _JsBuiltInEntropySource(); - } else { - // - // Assume that if we cannot get a built in Secure RNG then we are - // probably on NodeJS. - // - return _JsNodeEntropySource(); - } - } + EntropySource platformEntropySource() => + useBuiltInRng ? _JsBuiltInEntropySource() : _JsNodeEntropySource(); } // Uses the built in entropy source @@ -47,19 +31,18 @@ class _JsBuiltInEntropySource implements EntropySource { @override Uint8List getBytes(int len) { - return Uint8List.fromList( - List.generate(len, (i) => _src.nextInt(256))); + final Uint8List bytes = Uint8List(len); + for (int i = 0; i < len; i++) { + bytes[i] = _src.nextInt(256); + } + return bytes; } } /// class _JsNodeEntropySource implements EntropySource { @override - Uint8List getBytes(int len) { - var list = Uint8List(len); - NodeCrypto.randomFillSync(list.buffer.toJS); - return list; - } + Uint8List getBytes(int len) => NodeCrypto.randomBytes(len).toDart; } Platform getPlatform() => PlatformWeb.instance;