Skip to content

Commit a5f191b

Browse files
Use Web Crypto API for cookies and sessions (#11837)
1 parent 23ff35b commit a5f191b

File tree

24 files changed

+277
-565
lines changed

24 files changed

+277
-565
lines changed

.changeset/fast-plums-peel.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
"@react-router/architect": major
3+
"@react-router/cloudflare": major
4+
"@react-router/node": major
5+
"react-router": major
6+
---
7+
8+
For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages:
9+
10+
- `createCookie`
11+
- `createCookieSessionStorage`
12+
- `createMemorySessionStorage`
13+
- `createSessionStorage`
14+
15+
For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html)
16+
17+
Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed:
18+
19+
- `createCookieFactory`
20+
- `createSessionStorageFactory`
21+
- `createCookieSessionStorageFactory`
22+
- `createMemorySessionStorageFactory`

integration/set-cookie-revalidation-test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test.describe("set-cookie revalidation", () => {
1818
fixture = await createFixture({
1919
files: {
2020
"app/session.server.ts": js`
21-
import { createCookieSessionStorage } from "@react-router/node";
21+
import { createCookieSessionStorage } from "react-router";
2222
2323
export let MESSAGE_KEY = "message";
2424
@@ -33,8 +33,8 @@ test.describe("set-cookie revalidation", () => {
3333
`,
3434

3535
"app/root.tsx": js`
36-
import { json } from "react-router";
3736
import {
37+
json,
3838
Links,
3939
Meta,
4040
Outlet,

packages/react-router-architect/sessions/arcTableSessionStorage.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import * as crypto from "node:crypto";
21
import type {
32
SessionData,
43
SessionStorage,
54
SessionIdStorageStrategy,
65
} from "react-router";
7-
import { createSessionStorage } from "@react-router/node";
6+
import { createSessionStorage } from "react-router";
87
import arc from "@architect/functions";
98
import type { ArcTable } from "@architect/functions/types/tables";
109

@@ -64,7 +63,7 @@ export function createArcTableSessionStorage<
6463
async createData(data, expires) {
6564
let table = await getTable();
6665
while (true) {
67-
let randomBytes = crypto.randomBytes(8);
66+
let randomBytes = crypto.getRandomValues(new Uint8Array(8));
6867
// This storage manages an id space of 2^64 ids, which is far greater
6968
// than the maximum number of files allowed on an NTFS or ext4 volume
7069
// (2^32). However, the larger id space should help to avoid collisions

packages/react-router-cloudflare/crypto.ts

Lines changed: 0 additions & 53 deletions
This file was deleted.

packages/react-router-cloudflare/implementations.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

packages/react-router-cloudflare/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
export { createWorkersKVSessionStorage } from "./sessions/workersKVStorage";
22

3-
export {
4-
createCookie,
5-
createCookieSessionStorage,
6-
createMemorySessionStorage,
7-
createSessionStorage,
8-
} from "./implementations";
9-
103
export type {
114
createPagesFunctionHandlerParams,
125
GetLoadContextFunction,

packages/react-router-cloudflare/sessions/workersKVStorage.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import type {
33
SessionIdStorageStrategy,
44
SessionData,
55
} from "react-router";
6-
7-
import { createSessionStorage } from "../implementations";
6+
import { createSessionStorage } from "react-router";
87

98
interface WorkersKVSessionStorageOptions {
109
/**
@@ -36,8 +35,7 @@ export function createWorkersKVSessionStorage<
3635
cookie,
3736
async createData(data, expires) {
3837
while (true) {
39-
let randomBytes = new Uint8Array(8);
40-
crypto.getRandomValues(randomBytes);
38+
let randomBytes = crypto.getRandomValues(new Uint8Array(8));
4139
// This storage manages an id space of 2^64 ids, which is far greater
4240
// than the maximum number of files allowed on an NTFS or ext4 volume
4341
// (2^32). However, the larger id space should help to avoid collisions

packages/react-router-node/__tests__/sessions-test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* @jest-environment node
3+
*/
4+
15
import path from "node:path";
26
import { promises as fsp } from "node:fs";
37
import os from "node:os";

packages/react-router-node/crypto.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

packages/react-router-node/globals.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Request as NodeRequest,
77
Response as NodeResponse,
88
} from "undici";
9+
import { webcrypto as nodeWebCrypto } from "node:crypto";
910

1011
declare global {
1112
namespace NodeJS {
@@ -24,6 +25,8 @@ declare global {
2425

2526
ReadableStream: typeof ReadableStream;
2627
WritableStream: typeof WritableStream;
28+
29+
crypto: typeof nodeWebCrypto;
2730
}
2831
}
2932

@@ -44,4 +47,9 @@ export function installGlobals() {
4447
global.fetch = nodeFetch;
4548
// @ts-expect-error - overriding globals
4649
global.FormData = NodeFormData;
50+
51+
if (!global.crypto) {
52+
// @ts-expect-error - overriding globals
53+
global.crypto = nodeWebCrypto;
54+
}
4755
}

0 commit comments

Comments
 (0)