Skip to content

Commit 849991c

Browse files
authored
crypto: expose Web Crypto API on the global scope
PR-URL: #41938 Refs: https://developer.mozilla.org/en-US/docs/Web/API/crypto_property Refs: #41782 Refs: https://w3c.github.io/webcrypto Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Filip Skokan <[email protected]>
1 parent b53f927 commit 849991c

File tree

14 files changed

+145
-0
lines changed

14 files changed

+145
-0
lines changed

.eslintrc.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,5 +340,9 @@ module.exports = {
340340
Headers: 'readable',
341341
Request: 'readable',
342342
Response: 'readable',
343+
crypto: 'readable',
344+
Crypto: 'readable',
345+
CryptoKey: 'readable',
346+
SubtleCrypto: 'readable',
343347
},
344348
};

doc/api/cli.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,14 @@ added: v17.5.0
288288

289289
Enable experimental support for the [Fetch API][].
290290

291+
### `--experimental-global-webcrypto`
292+
293+
<!-- YAML
294+
added: REPLACEME
295+
-->
296+
297+
Expose the [Web Crypto API][] on the global scope.
298+
291299
### `--experimental-import-meta-resolve`
292300

293301
<!-- YAML
@@ -1580,6 +1588,7 @@ Node.js options that are allowed are:
15801588
* `--enable-source-maps`
15811589
* `--experimental-abortcontroller`
15821590
* `--experimental-fetch`
1591+
* `--experimental-global-webcrypto`
15831592
* `--experimental-import-meta-resolve`
15841593
* `--experimental-json-modules`
15851594
* `--experimental-loader`
@@ -1982,6 +1991,7 @@ $ node --max-old-space-size=1536 index.js
19821991
[Source Map]: https://sourcemaps.info/spec.html
19831992
[Subresource Integrity]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
19841993
[V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html
1994+
[Web Crypto API]: webcrypto.md
19851995
[`"type"`]: packages.md#type
19861996
[`--cpu-prof-dir`]: #--cpu-prof-dir
19871997
[`--diagnostic-dir`]: #--diagnostic-dirdirectory

doc/api/crypto.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ calling `require('crypto')` will result in an error being thrown.
4141

4242
When using CommonJS, the error thrown can be caught using try/catch:
4343

44+
<!-- eslint-skip -->
45+
4446
```cjs
4547
let crypto;
4648
try {

doc/api/globals.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,43 @@ added: v0.1.100
307307

308308
Used to print to stdout and stderr. See the [`console`][] section.
309309

310+
## `Crypto`
311+
312+
<!-- YAML
313+
added: REPLACEME
314+
-->
315+
316+
> Stability: 1 - Experimental. Enable this API with the
317+
> [`--experimental-global-webcrypto`][] CLI flag.
318+
319+
A browser-compatible implementation of {Crypto}. This global is available
320+
only if the Node.js binary was compiled with including support for the
321+
`crypto` module.
322+
323+
## `crypto`
324+
325+
<!-- YAML
326+
added: REPLACEME
327+
-->
328+
329+
> Stability: 1 - Experimental. Enable this API with the
330+
> [`--experimental-global-webcrypto`][] CLI flag.
331+
332+
A browser-compatible implementation of the [Web Crypto API][].
333+
334+
## `CryptoKey`
335+
336+
<!-- YAML
337+
added: REPLACEME
338+
-->
339+
340+
> Stability: 1 - Experimental. Enable this API with the
341+
> [`--experimental-global-webcrypto`][] CLI flag.
342+
343+
A browser-compatible implementation of {CryptoKey}. This global is available
344+
only if the Node.js binary was compiled with including support for the
345+
`crypto` module.
346+
310347
## `Event`
311348

312349
<!-- YAML
@@ -534,6 +571,19 @@ added: v17.0.0
534571

535572
The WHATWG [`structuredClone`][] method.
536573

574+
## `SubtleCrypto`
575+
576+
<!-- YAML
577+
added: REPLACEME
578+
-->
579+
580+
> Stability: 1 - Experimental. Enable this API with the
581+
> [`--experimental-global-webcrypto`][] CLI flag.
582+
583+
A browser-compatible implementation of {SubtleCrypto}. This global is available
584+
only if the Node.js binary was compiled with including support for the
585+
`crypto` module.
586+
537587
## `DOMException`
538588

539589
<!-- YAML
@@ -598,7 +648,9 @@ The object that acts as the namespace for all W3C
598648
[WebAssembly][webassembly-org] related functionality. See the
599649
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
600650

651+
[Web Crypto API]: webcrypto.md
601652
[`--experimental-fetch`]: cli.md#--experimental-fetch
653+
[`--experimental-global-webcrypto`]: cli.md#--experimental-global-webcrypto
602654
[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
603655
[`DOMException`]: https://developer.mozilla.org/en-US/docs/Web/API/DOMException
604656
[`EventTarget` and `Event` API]: events.md#eventtarget-and-event-api

doc/node.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ Enable Source Map V3 support for stack traces.
142142
.It Fl -experimental-fetch
143143
Enable experimental support for the Fetch API.
144144
.
145+
.It Fl -experimental-global-webcrypto
146+
Expose the Web Crypto API on the global scope.
147+
.
145148
.It Fl -experimental-import-meta-resolve
146149
Enable experimental ES modules support for import.meta.resolve().
147150
.

lib/.eslintrc.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ rules:
7979
message: "Use `const { atob } = require('buffer');` instead of the global."
8080
- name: btoa
8181
message: "Use `const { btoa } = require('buffer');` instead of the global."
82+
- name: crypto
83+
message: "Use `const { crypto } = require('internal/crypto/webcrypto');` instead of the global."
84+
- name: Crypto
85+
message: "Use `const { Crypto } = require('internal/crypto/webcrypto');` instead of the global."
86+
- name: CryptoKey
87+
message: "Use `const { CryptoKey } = require('internal/crypto/webcrypto');` instead of the global."
8288
- name: global
8389
message: "Use `const { globalThis } = primordials;` instead of `global`."
8490
- name: globalThis
@@ -89,6 +95,8 @@ rules:
8995
message: "Use `const { queueMicrotask } = require('internal/process/task_queues');` instead of the global."
9096
- name: structuredClone
9197
message: "Use `const { structuredClone } = require('internal/structured_clone');` instead of the global."
98+
- name: SubtleCrypto
99+
message: "Use `const { SubtleCrypto } = require('internal/crypto/webcrypto');` instead of the global."
92100
# Custom rules in tools/eslint-rules
93101
node-core/lowercase-name-for-primitive: error
94102
node-core/non-ascii-character: error

lib/internal/bootstrap/pre_execution.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const {
44
NumberParseInt,
55
ObjectDefineProperty,
6+
ObjectGetOwnPropertyDescriptor,
67
SafeMap,
78
SafeWeakMap,
89
StringPrototypeStartsWith,
@@ -36,6 +37,7 @@ function prepareMainThreadExecution(expandArgv1 = false) {
3637
setupInspectorHooks();
3738
setupWarningHandler();
3839
setupFetch();
40+
setupWebCrypto();
3941

4042
// Resolve the coverage directory to an absolute path, and
4143
// overwrite process.env so that the original path gets passed
@@ -162,6 +164,29 @@ function setupFetch() {
162164
exposeInterface(globalThis, 'Response', undici.Response);
163165
}
164166

167+
// TODO(aduh95): move this to internal/bootstrap/browser when the CLI flag is
168+
// removed.
169+
function setupWebCrypto() {
170+
if (!getOptionValue('--experimental-global-webcrypto')) {
171+
return;
172+
}
173+
174+
let webcrypto;
175+
ObjectDefineProperty(globalThis, 'crypto',
176+
ObjectGetOwnPropertyDescriptor({
177+
get crypto() {
178+
webcrypto ??= require('internal/crypto/webcrypto');
179+
return webcrypto.crypto;
180+
}
181+
}, 'crypto'));
182+
if (internalBinding('config').hasOpenSSL) {
183+
webcrypto ??= require('internal/crypto/webcrypto');
184+
exposeInterface(globalThis, 'Crypto', webcrypto.Crypto);
185+
exposeInterface(globalThis, 'CryptoKey', webcrypto.CryptoKey);
186+
exposeInterface(globalThis, 'SubtleCrypto', webcrypto.SubtleCrypto);
187+
}
188+
}
189+
165190
// Setup User-facing NODE_V8_COVERAGE environment variable that writes
166191
// ScriptCoverage to a specified file.
167192
function setupCoverageHooks(dir) {
@@ -503,6 +528,7 @@ module.exports = {
503528
setupCoverageHooks,
504529
setupWarningHandler,
505530
setupFetch,
531+
setupWebCrypto,
506532
setupDebugEnv,
507533
setupPerfHooks,
508534
prepareMainThreadExecution,

lib/internal/crypto/webcrypto.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,7 @@ ObjectDefineProperties(
808808

809809
module.exports = {
810810
Crypto,
811+
CryptoKey,
811812
SubtleCrypto,
812813
crypto,
813814
};

lib/internal/main/worker_thread.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const {
1818
setupInspectorHooks,
1919
setupWarningHandler,
2020
setupFetch,
21+
setupWebCrypto,
2122
setupDebugEnv,
2223
setupPerfHooks,
2324
initializeDeprecations,
@@ -69,6 +70,7 @@ setupDebugEnv();
6970

7071
setupWarningHandler();
7172
setupFetch();
73+
setupWebCrypto();
7274
initializeSourceMapsHandlers();
7375

7476
// Since worker threads cannot switch cwd, we do not need to

src/node_options.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
319319
"experimental Fetch API",
320320
&EnvironmentOptions::experimental_fetch,
321321
kAllowedInEnvironment);
322+
AddOption("--experimental-global-webcrypto",
323+
"expose experimental Web Crypto API on the global scope",
324+
&EnvironmentOptions::experimental_global_web_crypto,
325+
kAllowedInEnvironment);
322326
AddOption("--experimental-json-modules", "", NoOp{}, kAllowedInEnvironment);
323327
AddOption("--experimental-loader",
324328
"use the specified module as a custom loader",

0 commit comments

Comments
 (0)