From 2bb1c6d6fe5f8e3d683e3ddcc320e81268322c23 Mon Sep 17 00:00:00 2001 From: Matthew Williams Date: Mon, 28 Mar 2022 20:34:30 +0100 Subject: [PATCH 1/5] feat(remix-server-runtime): throw error when cookie limit is reached (#2155) --- contributors.yml | 1 + .../__tests__/sessions-test.ts | 10 +++++ .../sessions/cookieStorage.ts | 37 +++++++++++-------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/contributors.yml b/contributors.yml index 2adc5ef5f43..32d060113d9 100644 --- a/contributors.yml +++ b/contributors.yml @@ -189,6 +189,7 @@ - matthew-burfield - Matthew-Mallimo - MatthewAlbrecht +- matt-l-w - mattmazzola - mattstobbs - mbarto diff --git a/packages/remix-server-runtime/__tests__/sessions-test.ts b/packages/remix-server-runtime/__tests__/sessions-test.ts index da5039dfe42..74e6bbffa38 100644 --- a/packages/remix-server-runtime/__tests__/sessions-test.ts +++ b/packages/remix-server-runtime/__tests__/sessions-test.ts @@ -129,6 +129,16 @@ describe("Cookie session storage", () => { expect(setCookie).toContain("Path=/"); }); + it("throws an error when the cookie size exceeds 4096 bytes", async () => { + let { getSession, commitSession } = createCookieSessionStorage({ + cookie: { secrets: ["secret1"] }, + }); + let session = await getSession(); + let longString = new Array(4097).fill("a").join(""); + session.set("over4096bytes", longString); + await expect(() => commitSession(session)).rejects.toThrow(); + }); + describe("when a new secret shows up in the rotation", () => { it("unsigns old session cookies using the old secret and encodes new cookies using the new secret", async () => { let { getSession, commitSession } = createCookieSessionStorage({ diff --git a/packages/remix-server-runtime/sessions/cookieStorage.ts b/packages/remix-server-runtime/sessions/cookieStorage.ts index bd4e0efdf54..6d76987d68d 100644 --- a/packages/remix-server-runtime/sessions/cookieStorage.ts +++ b/packages/remix-server-runtime/sessions/cookieStorage.ts @@ -35,20 +35,27 @@ export const createCookieSessionStorageFactory = warnOnceAboutSigningSessionCookie(cookie); - return { - async getSession(cookieHeader, options) { - return createSession( - (cookieHeader && (await cookie.parse(cookieHeader, options))) || {} + return { + async getSession(cookieHeader, options) { + return createSession( + (cookieHeader && (await cookie.parse(cookieHeader, options))) || {} + ); + }, + async commitSession(session, options) { + let serializedCookie = await cookie.serialize(session.data, options); + if (serializedCookie.length > 4096) { + throw new Error( + "Cookie length will exceed browser maximum. Length: " + + serializedCookie.length ); - }, - async commitSession(session, options) { - return cookie.serialize(session.data, options); - }, - async destroySession(_session, options) { - return cookie.serialize("", { - ...options, - expires: new Date(0), - }); - }, - }; + } + return serializedCookie; + }, + async destroySession(_session, options) { + return cookie.serialize("", { + ...options, + expires: new Date(0), + }); + }, }; +}; From bf29222217355fdb458cfb135eff08e447ac95a4 Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Mon, 28 Mar 2022 19:36:53 +0000 Subject: [PATCH 2/5] chore: format --- .../sessions/cookieStorage.ts | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/remix-server-runtime/sessions/cookieStorage.ts b/packages/remix-server-runtime/sessions/cookieStorage.ts index 6d76987d68d..90d0a34da9d 100644 --- a/packages/remix-server-runtime/sessions/cookieStorage.ts +++ b/packages/remix-server-runtime/sessions/cookieStorage.ts @@ -35,27 +35,27 @@ export const createCookieSessionStorageFactory = warnOnceAboutSigningSessionCookie(cookie); - return { - async getSession(cookieHeader, options) { - return createSession( - (cookieHeader && (await cookie.parse(cookieHeader, options))) || {} - ); - }, - async commitSession(session, options) { - let serializedCookie = await cookie.serialize(session.data, options); - if (serializedCookie.length > 4096) { - throw new Error( - "Cookie length will exceed browser maximum. Length: " + - serializedCookie.length + return { + async getSession(cookieHeader, options) { + return createSession( + (cookieHeader && (await cookie.parse(cookieHeader, options))) || {} ); - } - return serializedCookie; - }, - async destroySession(_session, options) { - return cookie.serialize("", { - ...options, - expires: new Date(0), - }); - }, + }, + async commitSession(session, options) { + let serializedCookie = await cookie.serialize(session.data, options); + if (serializedCookie.length > 4096) { + throw new Error( + "Cookie length will exceed browser maximum. Length: " + + serializedCookie.length + ); + } + return serializedCookie; + }, + async destroySession(_session, options) { + return cookie.serialize("", { + ...options, + expires: new Date(0), + }); + }, + }; }; -}; From b936125fb84544301e6e64eeafb2616a78e32d06 Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Mon, 28 Mar 2022 15:24:29 -0700 Subject: [PATCH 3/5] fix(cli): stop CLI from logging full stack trace on known errors (#2525) --- packages/create-remix/cli.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/create-remix/cli.ts b/packages/create-remix/cli.ts index efa5b71b6b1..0a0f03a6628 100644 --- a/packages/create-remix/cli.ts +++ b/packages/create-remix/cli.ts @@ -1,11 +1,13 @@ import { cli } from "@remix-run/dev"; -cli.run(["create", ...process.argv.slice(2)]).then( - () => { +let args = process.argv.slice(2); + +cli + .run(["create", ...args]) + .then(() => { process.exit(0); - }, - (error: Error) => { - console.error(error); + }) + .catch((error: Error) => { + console.error(args.includes("--debug") ? error : error.message); process.exit(1); - } -); + }); From a1815fa0b53edd00e9962602079f132500feab55 Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Mon, 28 Mar 2022 15:36:18 -0700 Subject: [PATCH 4/5] chore: revert gists app dynamic port --- fixtures/gists-app/server.js | 116 +++++++++++++++++------------------ 1 file changed, 56 insertions(+), 60 deletions(-) diff --git a/fixtures/gists-app/server.js b/fixtures/gists-app/server.js index bd0e782ba78..fa163f34114 100644 --- a/fixtures/gists-app/server.js +++ b/fixtures/gists-app/server.js @@ -2,74 +2,70 @@ const express = require("express"); const morgan = require("morgan"); const compression = require("compression"); const { createRequestHandler } = require("@remix-run/express"); -const getPort = require("get-port"); -getPort({ port: process.env.PORT || 3000 }).then((port) => { - if (process.env.NODE_ENV === "test") { - class MockConsole { - assert() {} - clear() {} - count() {} - countReset() {} - debug() {} - dir() {} - dirxml() {} - error() {} - group() {} - groupCollapsed() {} - groupEnd() {} - info() {} - log() {} - table() {} - time() {} - timeEnd() {} - timeLog() {} - timeStamp() {} - trace() {} - warn() {} - } - global.console = new MockConsole(); +const port = process.env.PORT || 3000; + +if (process.env.NODE_ENV === "test") { + class MockConsole { + assert() {} + clear() {} + count() {} + countReset() {} + debug() {} + dir() {} + dirxml() {} + error() {} + group() {} + groupCollapsed() {} + groupEnd() {} + info() {} + log() {} + table() {} + time() {} + timeEnd() {} + timeLog() {} + timeStamp() {} + trace() {} + warn() {} } + global.console = new MockConsole(); +} - let app = express(); +let app = express(); - app.use(compression()); +app.use(compression()); - app.use( - express.static("public", { - // maxAge: process.env.NODE_ENV === "production" ? "1y" : undefined - maxAge: "1y", - }) - ); +app.use( + express.static("public", { + // maxAge: process.env.NODE_ENV === "production" ? "1y" : undefined + maxAge: "1y", + }) +); - app.get("/fails.css", (req, res) => { - res.status(500).send("Boom! No CSS here!"); - }); +app.get("/fails.css", (req, res) => { + res.status(500).send("Boom! No CSS here!"); +}); - // server-side redirect - app.get("/user-gists/:username", (req, res) => { - res.redirect(301, `/gists/${req.params.username}`); - }); +// server-side redirect +app.get("/user-gists/:username", (req, res) => { + res.redirect(301, `/gists/${req.params.username}`); +}); - if ( - process.env.NODE_ENV !== "production" && - process.env.NODE_ENV !== "test" - ) { - app.use(morgan("dev")); - } +if (process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test") { + app.use(morgan("dev")); +} - app.all( - "*", - createRequestHandler({ - build: require("@remix-run/dev/server-build"), - getLoadContext() { - return { userId: 4 }; - }, - }) - ); +app.all( + "*", + createRequestHandler({ + build: require("@remix-run/dev/server-build"), + getLoadContext() { + return { userId: 4 }; + }, + }) +); - app.listen(port, () => { - console.log(`Gists app running on port ${port}`); - console.log(`http://localhost:${port}`); - }); +app.listen(port, () => { + console.log(`Gists app running on port ${port}`); + console.log(`http://localhost:${port}`); }); From 21ec8370cfce6943212423d43b2046c484a10590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Tue, 29 Mar 2022 06:15:49 +0200 Subject: [PATCH 5/5] fix(remix-react): use `.flat().map()` instead of `flatMap` in `Meta` component (#2531) --- packages/remix-react/components.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx index 077cac26812..3fe034b47ea 100644 --- a/packages/remix-react/components.tsx +++ b/packages/remix-react/components.tsx @@ -678,7 +678,7 @@ export function Meta() { // Open Graph tags use the `property` attribute, while other meta tags // use `name`. See https://ogp.me/ let isOpenGraphTag = name.startsWith("og:"); - return [value].flatMap((content) => { + return [value].flat().map((content) => { if (isOpenGraphTag) { return (