mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
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>
This commit is contained in:
parent
b53f927a52
commit
849991c6c4
14 changed files with 145 additions and 0 deletions
|
@ -340,5 +340,9 @@ module.exports = {
|
|||
Headers: 'readable',
|
||||
Request: 'readable',
|
||||
Response: 'readable',
|
||||
crypto: 'readable',
|
||||
Crypto: 'readable',
|
||||
CryptoKey: 'readable',
|
||||
SubtleCrypto: 'readable',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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().
|
||||
.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -808,6 +808,7 @@ ObjectDefineProperties(
|
|||
|
||||
module.exports = {
|
||||
Crypto,
|
||||
CryptoKey,
|
||||
SubtleCrypto,
|
||||
crypto,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
13
test/parallel/test-global-webcrypto-classes.js
Normal file
13
test/parallel/test-global-webcrypto-classes.js
Normal file
|
@ -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);
|
13
test/parallel/test-global-webcrypto.js
Normal file
13
test/parallel/test-global-webcrypto.js
Normal file
|
@ -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);
|
Loading…
Add table
Add a link
Reference in a new issue