From ed4e7eff549a3af97025e976fe53f42922e673f0 Mon Sep 17 00:00:00 2001 From: Musiker15 Date: Mon, 17 Aug 2026 23:06:27 +0200 Subject: [PATCH] chore(deps): bump ioredis to 6.0.0 and pin the RESP2 wire protocol ioredis 6 negotiates RESP3 by default and requires Node 20+. The engine requirement is already satisfied (>=22), but the protocol switch is not covered by CI: the Redis client is fully mocked in the unit tests, and the CI service runs the default user on localhost, while production connects as an ACL user over an authenticated URL. That combination is the problem. getRedis() is deliberately fail-open, so a handshake that the server rejects would not surface as an error page or a crash. Rate limiting on the public submit endpoint would simply stop applying, leaving only a log line behind. Set protocol: 2 to keep the v5 wire format. The only consumer is the fixed window EVAL in the rate limiter, which gains nothing from RESP3, so there is no reason to take that risk as a side effect of a version bump. RESP3 can be adopted later as its own change, verified against the live server. Supersedes #238, which bumps the same dependency without the pin. --- apps/web/package.json | 2 +- apps/web/src/lib/redis.ts | 5 +++++ pnpm-lock.yaml | 29 ++++++++++------------------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index ec21322..3a95260 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -22,7 +22,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "exceljs": "^4.4.0", - "ioredis": "^5.4.2", + "ioredis": "^6.0.0", "iron-session": "^8.0.4", "next": "^16.3.1", "next-themes": "^0.4.4", diff --git a/apps/web/src/lib/redis.ts b/apps/web/src/lib/redis.ts index 4c334e6..a986b7a 100644 --- a/apps/web/src/lib/redis.ts +++ b/apps/web/src/lib/redis.ts @@ -20,6 +20,11 @@ export function getRedis(): Redis | null { } const client = new Redis(url, { + // ioredis 6 negotiates RESP3 by default. Stay on the v5 wire protocol: the + // only consumer is the rate limiter's EVAL, which gains nothing from RESP3, + // and a failed handshake would be silent (the limiter fails open, see + // below). Revisit deliberately, with a check against the live server. + protocol: 2, // Fail fast instead of queueing/retrying forever, so a Redis outage can't // stall request handling — the rate limiter just falls open. maxRetriesPerRequest: 1, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 029a1ce..1eb5d8f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,8 +127,8 @@ importers: specifier: ^4.4.0 version: 4.4.0 ioredis: - specifier: ^5.4.2 - version: 5.11.1 + specifier: ^6.0.0 + version: 6.0.0 iron-session: specifier: ^8.0.4 version: 8.0.4 @@ -767,8 +767,8 @@ packages: cpu: [x64] os: [win32] - '@ioredis/commands@1.10.0': - resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==} + '@ioredis/commands@2.0.0': + resolution: {integrity: sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg==} '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -2057,9 +2057,9 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} - ioredis@5.11.1: - resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==} - engines: {node: '>=12.22.0'} + ioredis@6.0.0: + resolution: {integrity: sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==} + engines: {node: '>=20.0.0'} iron-session@8.0.4: resolution: {integrity: sha512-9ivNnaKOd08osD0lJ3i6If23GFS2LsxyMU8Gf/uBUEgm8/8CC1hrrCHFDpMo3IFbpBgwoo/eairRsaD3c5itxA==} @@ -2638,10 +2638,6 @@ packages: resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} engines: {node: '>=4'} - redis-parser@3.0.0: - resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} - engines: {node: '>=4'} - remeda@2.33.4: resolution: {integrity: sha512-ygHswjlc/opg2VrtiYvUOPLjxjtdKvjGz1/plDhkG66hjNjFr1xmfrs2ClNFo/E6TyUFiwYNh53bKV26oBoMGQ==} @@ -3600,7 +3596,7 @@ snapshots: '@img/sharp-win32-x64@0.35.3': optional: true - '@ioredis/commands@1.10.0': {} + '@ioredis/commands@2.0.0': {} '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -4932,14 +4928,13 @@ snapshots: internmap@2.0.3: {} - ioredis@5.11.1: + ioredis@6.0.0: dependencies: - '@ioredis/commands': 1.10.0 + '@ioredis/commands': 2.0.0 cluster-key-slot: 1.1.1 debug: 4.4.3 denque: 2.1.0 redis-errors: 1.2.0 - redis-parser: 3.0.0 standard-as-callback: 2.1.0 transitivePeerDependencies: - supports-color @@ -5414,10 +5409,6 @@ snapshots: redis-errors@1.2.0: {} - redis-parser@3.0.0: - dependencies: - redis-errors: 1.2.0 - remeda@2.33.4: {} require-directory@2.1.1: {}