Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine du Hamel <duhamelantoine1995@gmail.com>2022-02-14 19:14:49 +0300
committerGitHub <noreply@github.com>2022-02-14 19:14:49 +0300
commit849991c6c47a0e05365feb4c9b1fb841924a5192 (patch)
tree056d4fc7618a0834f15afffa91aa013c37f13c0e
parentb53f927a521e6bae7e12583634b4a21aef348f13 (diff)
crypto: expose Web Crypto API on the global scope
PR-URL: https://github.com/nodejs/node/pull/41938 Refs: https://developer.mozilla.org/en-US/docs/Web/API/crypto_property Refs: https://github.com/nodejs/node/pull/41782 Refs: https://w3c.github.io/webcrypto Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaƫl Zasso <targos@protonmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
-rw-r--r--.eslintrc.js4
-rw-r--r--doc/api/cli.md10
-rw-r--r--doc/api/crypto.md2
-rw-r--r--doc/api/globals.md52
-rw-r--r--doc/node.13
-rw-r--r--lib/.eslintrc.yaml8
-rw-r--r--lib/internal/bootstrap/pre_execution.js26
-rw-r--r--lib/internal/crypto/webcrypto.js1
-rw-r--r--lib/internal/main/worker_thread.js2
-rw-r--r--src/node_options.cc4
-rw-r--r--src/node_options.h1
-rw-r--r--test/common/index.js6
-rw-r--r--test/parallel/test-global-webcrypto-classes.js13
-rw-r--r--test/parallel/test-global-webcrypto.js13
14 files changed, 145 insertions, 0 deletions
diff --git a/.eslintrc.js b/.eslintrc.js
index da17fd47acd..c7c7cc56051 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -340,5 +340,9 @@ module.exports = {
Headers: 'readable',
Request: 'readable',
Response: 'readable',
+ crypto: 'readable',
+ Crypto: 'readable',
+ CryptoKey: 'readable',
+ SubtleCrypto: 'readable',
},
};
diff --git a/doc/api/cli.md b/doc/api/cli.md
index 10500f130a6..a551a3fff9c 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -288,6 +288,14 @@ added: v17.5.0
Enable experimental support for the [Fetch API][].
+### `--experimental-global-webcrypto`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+Expose the [Web Crypto API][] on the global scope.
+
### `--experimental-import-meta-resolve`
<!-- YAML
@@ -1580,6 +1588,7 @@ Node.js options that are allowed are:
* `--enable-source-maps`
* `--experimental-abortcontroller`
* `--experimental-fetch`
+* `--experimental-global-webcrypto`
* `--experimental-import-meta-resolve`
* `--experimental-json-modules`
* `--experimental-loader`
@@ -1982,6 +1991,7 @@ $ node --max-old-space-size=1536 index.js
[Source Map]: https://sourcemaps.info/spec.html
[Subresource Integrity]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
[V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html
+[Web Crypto API]: webcrypto.md
[`"type"`]: packages.md#type
[`--cpu-prof-dir`]: #--cpu-prof-dir
[`--diagnostic-dir`]: #--diagnostic-dirdirectory
diff --git a/doc/api/crypto.md b/doc/api/crypto.md
index 0e56f12a6fd..e5b83eb4ff5 100644
--- a/doc/api/crypto.md
+++ b/doc/api/crypto.md
@@ -41,6 +41,8 @@ calling `require('crypto')` will result in an error being thrown.
When using CommonJS, the error thrown can be caught using try/catch:
+<!-- eslint-skip -->
+
```cjs
let crypto;
try {
diff --git a/doc/api/globals.md b/doc/api/globals.md
index 1fa6801dda6..f4ea4fb4747 100644
--- a/doc/api/globals.md
+++ b/doc/api/globals.md
@@ -307,6 +307,43 @@ added: v0.1.100
Used to print to stdout and stderr. See the [`console`][] section.
+## `Crypto`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - Experimental. Enable this API with the
+> [`--experimental-global-webcrypto`][] CLI flag.
+
+A browser-compatible implementation of {Crypto}. This global is available
+only if the Node.js binary was compiled with including support for the
+`crypto` module.
+
+## `crypto`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - Experimental. Enable this API with the
+> [`--experimental-global-webcrypto`][] CLI flag.
+
+A browser-compatible implementation of the [Web Crypto API][].
+
+## `CryptoKey`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - Experimental. Enable this API with the
+> [`--experimental-global-webcrypto`][] CLI flag.
+
+A browser-compatible implementation of {CryptoKey}. This global is available
+only if the Node.js binary was compiled with including support for the
+`crypto` module.
+
## `Event`
<!-- YAML
@@ -534,6 +571,19 @@ added: v17.0.0
The WHATWG [`structuredClone`][] method.
+## `SubtleCrypto`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+> Stability: 1 - Experimental. Enable this API with the
+> [`--experimental-global-webcrypto`][] CLI flag.
+
+A browser-compatible implementation of {SubtleCrypto}. This global is available
+only if the Node.js binary was compiled with including support for the
+`crypto` module.
+
## `DOMException`
<!-- YAML
@@ -598,7 +648,9 @@ The object that acts as the namespace for all W3C
[WebAssembly][webassembly-org] related functionality. See the
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
+[Web Crypto API]: webcrypto.md
[`--experimental-fetch`]: cli.md#--experimental-fetch
+[`--experimental-global-webcrypto`]: cli.md#--experimental-global-webcrypto
[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
[`DOMException`]: https://developer.mozilla.org/en-US/docs/Web/API/DOMException
[`EventTarget` and `Event` API]: events.md#eventtarget-and-event-api
diff --git a/doc/node.1 b/doc/node.1
index 86a5bd865ae..972487be121 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -142,6 +142,9 @@ Enable Source Map V3 support for stack traces.
.It Fl -experimental-fetch
Enable experimental support for the Fetch API.
.
+.It Fl -experimental-global-webcrypto
+Expose the Web Crypto API on the global scope.
+.
.It Fl -experimental-import-meta-resolve
Enable experimental ES modules support for import.meta.resolve().
.
diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml
index c5e1058a306..709c5f4c93e 100644
--- a/lib/.eslintrc.yaml
+++ b/lib/.eslintrc.yaml
@@ -79,6 +79,12 @@ rules:
message: "Use `const { atob } = require('buffer');` instead of the global."
- name: btoa
message: "Use `const { btoa } = require('buffer');` instead of the global."
+ - name: crypto
+ message: "Use `const { crypto } = require('internal/crypto/webcrypto');` instead of the global."
+ - name: Crypto
+ message: "Use `const { Crypto } = require('internal/crypto/webcrypto');` instead of the global."
+ - name: CryptoKey
+ message: "Use `const { CryptoKey } = require('internal/crypto/webcrypto');` instead of the global."
- name: global
message: "Use `const { globalThis } = primordials;` instead of `global`."
- name: globalThis
@@ -89,6 +95,8 @@ rules:
message: "Use `const { queueMicrotask } = require('internal/process/task_queues');` instead of the global."
- name: structuredClone
message: "Use `const { structuredClone } = require('internal/structured_clone');` instead of the global."
+ - name: SubtleCrypto
+ message: "Use `const { SubtleCrypto } = require('internal/crypto/webcrypto');` instead of the global."
# Custom rules in tools/eslint-rules
node-core/lowercase-name-for-primitive: error
node-core/non-ascii-character: error
diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index 1fe56478e0a..ca7063ac90d 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -3,6 +3,7 @@
const {
NumberParseInt,
ObjectDefineProperty,
+ ObjectGetOwnPropertyDescriptor,
SafeMap,
SafeWeakMap,
StringPrototypeStartsWith,
@@ -36,6 +37,7 @@ function prepareMainThreadExecution(expandArgv1 = false) {
setupInspectorHooks();
setupWarningHandler();
setupFetch();
+ setupWebCrypto();
// Resolve the coverage directory to an absolute path, and
// overwrite process.env so that the original path gets passed
@@ -162,6 +164,29 @@ function setupFetch() {
exposeInterface(globalThis, 'Response', undici.Response);
}
+// TODO(aduh95): move this to internal/bootstrap/browser when the CLI flag is
+// removed.
+function setupWebCrypto() {
+ if (!getOptionValue('--experimental-global-webcrypto')) {
+ return;
+ }
+
+ let webcrypto;
+ ObjectDefineProperty(globalThis, 'crypto',
+ ObjectGetOwnPropertyDescriptor({
+ get crypto() {
+ webcrypto ??= require('internal/crypto/webcrypto');
+ return webcrypto.crypto;
+ }
+ }, 'crypto'));
+ if (internalBinding('config').hasOpenSSL) {
+ webcrypto ??= require('internal/crypto/webcrypto');
+ exposeInterface(globalThis, 'Crypto', webcrypto.Crypto);
+ exposeInterface(globalThis, 'CryptoKey', webcrypto.CryptoKey);
+ exposeInterface(globalThis, 'SubtleCrypto', webcrypto.SubtleCrypto);
+ }
+}
+
// Setup User-facing NODE_V8_COVERAGE environment variable that writes
// ScriptCoverage to a specified file.
function setupCoverageHooks(dir) {
@@ -503,6 +528,7 @@ module.exports = {
setupCoverageHooks,
setupWarningHandler,
setupFetch,
+ setupWebCrypto,
setupDebugEnv,
setupPerfHooks,
prepareMainThreadExecution,
diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js
index c022bb44223..8e3822494be 100644
--- a/lib/internal/crypto/webcrypto.js
+++ b/lib/internal/crypto/webcrypto.js
@@ -808,6 +808,7 @@ ObjectDefineProperties(
module.exports = {
Crypto,
+ CryptoKey,
SubtleCrypto,
crypto,
};
diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js
index 5e24b84e14c..a5816f1f1cf 100644
--- a/lib/internal/main/worker_thread.js
+++ b/lib/internal/main/worker_thread.js
@@ -18,6 +18,7 @@ const {
setupInspectorHooks,
setupWarningHandler,
setupFetch,
+ setupWebCrypto,
setupDebugEnv,
setupPerfHooks,
initializeDeprecations,
@@ -69,6 +70,7 @@ setupDebugEnv();
setupWarningHandler();
setupFetch();
+setupWebCrypto();
initializeSourceMapsHandlers();
// Since worker threads cannot switch cwd, we do not need to
diff --git a/src/node_options.cc b/src/node_options.cc
index bac3de2404b..ab3b736e07d 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -319,6 +319,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
"experimental Fetch API",
&EnvironmentOptions::experimental_fetch,
kAllowedInEnvironment);
+ AddOption("--experimental-global-webcrypto",
+ "expose experimental Web Crypto API on the global scope",
+ &EnvironmentOptions::experimental_global_web_crypto,
+ kAllowedInEnvironment);
AddOption("--experimental-json-modules", "", NoOp{}, kAllowedInEnvironment);
AddOption("--experimental-loader",
"use the specified module as a custom loader",
diff --git a/src/node_options.h b/src/node_options.h
index 6042f5e7f5e..0ded5d89bee 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -108,6 +108,7 @@ class EnvironmentOptions : public Options {
std::string dns_result_order;
bool enable_source_maps = false;
bool experimental_fetch = false;
+ bool experimental_global_web_crypto = false;
bool experimental_https_modules = false;
std::string experimental_specifier_resolution;
bool experimental_wasm_modules = false;
diff --git a/test/common/index.js b/test/common/index.js
index fdffecb9af1..46a59b54d52 100644
--- a/test/common/index.js
+++ b/test/common/index.js
@@ -308,6 +308,12 @@ if (global.fetch) {
global.Headers,
);
}
+if (hasCrypto && global.crypto) {
+ knownGlobals.push(global.crypto);
+ knownGlobals.push(global.Crypto);
+ knownGlobals.push(global.CryptoKey);
+ knownGlobals.push(global.SubtleCrypto);
+}
function allowGlobals(...allowlist) {
knownGlobals = knownGlobals.concat(allowlist);
diff --git a/test/parallel/test-global-webcrypto-classes.js b/test/parallel/test-global-webcrypto-classes.js
new file mode 100644
index 00000000000..083592bd922
--- /dev/null
+++ b/test/parallel/test-global-webcrypto-classes.js
@@ -0,0 +1,13 @@
+// Flags: --experimental-global-webcrypto --expose-internals
+'use strict';
+
+const common = require('../common');
+if (!common.hasCrypto)
+ common.skip('missing crypto');
+
+const assert = require('assert');
+const webcrypto = require('internal/crypto/webcrypto');
+
+assert.strictEqual(Crypto, webcrypto.Crypto);
+assert.strictEqual(CryptoKey, webcrypto.CryptoKey);
+assert.strictEqual(SubtleCrypto, webcrypto.SubtleCrypto);
diff --git a/test/parallel/test-global-webcrypto.js b/test/parallel/test-global-webcrypto.js
new file mode 100644
index 00000000000..70f84a1b3a0
--- /dev/null
+++ b/test/parallel/test-global-webcrypto.js
@@ -0,0 +1,13 @@
+// Flags: --experimental-global-webcrypto
+'use strict';
+
+const common = require('../common');
+if (!common.hasCrypto)
+ common.skip('missing crypto');
+
+const assert = require('assert');
+const crypto = require('crypto');
+
+assert.strictEqual(globalThis.crypto, crypto.webcrypto);
+assert.strictEqual(Crypto, crypto.webcrypto.constructor);
+assert.strictEqual(SubtleCrypto, crypto.webcrypto.subtle.constructor);