From 6ba189b86fcd644d254358f1dceaa8da7f9e6df0 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 08:48:35 -0700 Subject: [PATCH 01/13] fix: await params in features route to fix 404 errors - Update ServicePage to properly await params Promise in Next.js 15 - Replace type assertion workaround with proper interface typing - Fixes issue where clicking features resulted in 404 errors - Matches pattern used in products and events routes --- src/app/features/[slug]/page.tsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/app/features/[slug]/page.tsx b/src/app/features/[slug]/page.tsx index 82ace1ba..1ae7cd2d 100644 --- a/src/app/features/[slug]/page.tsx +++ b/src/app/features/[slug]/page.tsx @@ -6,15 +6,16 @@ import { SchemaInjector, buildServiceJsonLd } from "@/utils/seo/schema"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; -// Next.js 15+ Dynamic Route Compatibility Workaround -// Use Promise type for params in generateMetadata; use type assertion inside the page function. -// This prevents type errors in production builds due to Next.js 15+ breaking changes. +// Next.js 15+ Dynamic Route Compatibility +// Params are now Promises and must be awaited in both generateMetadata and page components. + +interface ServicePageProps { + params: Promise<{ slug: string }>; +} export async function generateMetadata({ params, -}: { - params: Promise<{ slug: string }>; -}): Promise { +}: ServicePageProps): Promise { const { slug } = await params; const allServices: ServiceItemData[] = Object.values(allServicesRaw).flatMap( (category) => Object.values(category), @@ -22,13 +23,13 @@ export async function generateMetadata({ return getSeoMetadataForService(slug, allServices); } -export default async function ServicePage(props: unknown) { - const { params } = props as { params: { slug: string } }; +export default async function ServicePage({ params }: ServicePageProps) { + const { slug } = await params; const allServices: ServiceItemData[] = Object.values(allServicesRaw).flatMap( (category) => Object.values(category), ); const service = - allServices.find((s) => s.slugDetails.slug === params.slug) || null; + allServices.find((s) => s.slugDetails.slug === slug) || null; if (!service) return notFound(); const serviceSchema = buildServiceJsonLd(service); From 3172bb189d0f28c0ae8bcc9ad46cac8a4b1bd2b7 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 08:55:57 -0700 Subject: [PATCH 02/13] refactor: remove repetitive text from testimonials microcopy - Remove duplicate 'Stop dialing. Start closing...' text from LIVE_MICROCOPY - Put 'Review the rollout steps' on its own line using
tag - Update PersonaCTA to support
tags in microcopy rendering - Improves readability and removes redundancy before testimonials section --- .../src/components/PersonaCTA.tsx | 105 +++++++++++------- .../heros/live-dynamic-hero-demo/_config.ts | 2 +- 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/src/components/dynamic-hero/src/components/PersonaCTA.tsx b/src/components/dynamic-hero/src/components/PersonaCTA.tsx index 72d019a5..daa8316f 100644 --- a/src/components/dynamic-hero/src/components/PersonaCTA.tsx +++ b/src/components/dynamic-hero/src/components/PersonaCTA.tsx @@ -77,51 +77,78 @@ const PersonaCTA: FC = ({ const elements: ReactNode[] = []; let lastIndex = 0; const linkRegex = /(.*?)<\/link>/gi; + const brRegex = //gi; + const allMatches: Array<{ type: "link" | "br"; index: number; match: RegExpExecArray }> = []; + + // Collect all link matches let match: RegExpExecArray | null = linkRegex.exec(copy); + while (match !== null) { + allMatches.push({ type: "link", index: match.index, match }); + match = linkRegex.exec(copy); + } + // Collect all br matches + brRegex.lastIndex = 0; + match = brRegex.exec(copy); while (match !== null) { - const [fullMatch, href, text] = match; - if (match.index > lastIndex) { - elements.push(copy.slice(lastIndex, match.index)); + allMatches.push({ type: "br", index: match.index, match }); + match = brRegex.exec(copy); + } + + // Sort matches by index + allMatches.sort((a, b) => a.index - b.index); + + // Process matches in order + for (const item of allMatches) { + const { type, index, match: currentMatch } = item; + if (index > lastIndex) { + elements.push(copy.slice(lastIndex, index)); } - elements.push( - - - {text} - - - , - ); - lastIndex = match.index + fullMatch.length; - match = linkRegex.exec(copy); + + {text} + + + , + ); + lastIndex = index + currentMatch[0].length; + } else if (type === "br") { + elements.push(
); + lastIndex = index + currentMatch[0].length; + } } + if (lastIndex < copy.length) { elements.push(copy.slice(lastIndex)); } diff --git a/src/components/home/heros/live-dynamic-hero-demo/_config.ts b/src/components/home/heros/live-dynamic-hero-demo/_config.ts index 925c0f02..405fe390 100644 --- a/src/components/home/heros/live-dynamic-hero-demo/_config.ts +++ b/src/components/home/heros/live-dynamic-hero-demo/_config.ts @@ -222,7 +222,7 @@ export const LIVE_SECONDARY_CTA = { }; export const LIVE_MICROCOPY = - 'Stop dialing. Start closing. Your AI coworker books qualified sellers while you sleep. Review the rollout steps. "People buy from people who make them feel capable and confident." - Dale Carnegie.'; + 'Review the rollout steps
"People buy from people who make them feel capable and confident." - Dale Carnegie.'; export const LIVE_SOCIAL_PROOF = { ...DEFAULT_HERO_SOCIAL_PROOF, From 0ca8b7fd1cb92ba59eabe4301fa1ff7f3b9f0692 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 08:56:33 -0700 Subject: [PATCH 03/13] fix: resolve linting issues in PersonaCTA - Prefix unused fullMatch variable with underscore - Format allMatches type definition across multiple lines --- src/components/dynamic-hero/src/components/PersonaCTA.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/dynamic-hero/src/components/PersonaCTA.tsx b/src/components/dynamic-hero/src/components/PersonaCTA.tsx index daa8316f..8ee3eff9 100644 --- a/src/components/dynamic-hero/src/components/PersonaCTA.tsx +++ b/src/components/dynamic-hero/src/components/PersonaCTA.tsx @@ -78,7 +78,11 @@ const PersonaCTA: FC = ({ let lastIndex = 0; const linkRegex = /(.*?)<\/link>/gi; const brRegex = //gi; - const allMatches: Array<{ type: "link" | "br"; index: number; match: RegExpExecArray }> = []; + const allMatches: Array<{ + type: "link" | "br"; + index: number; + match: RegExpExecArray; + }> = []; // Collect all link matches let match: RegExpExecArray | null = linkRegex.exec(copy); @@ -106,7 +110,7 @@ const PersonaCTA: FC = ({ } if (type === "link") { - const [fullMatch, href, text] = currentMatch; + const [_fullMatch, href, text] = currentMatch; elements.push( Date: Sun, 7 Dec 2025 08:57:15 -0700 Subject: [PATCH 04/13] refactor: update hobby time badge text format - Change from '+15 hours hobby time by the week' to '15+ hobby time this week' - Improves readability and matches user preference --- src/components/home/ReactivateCampaignBadges.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/home/ReactivateCampaignBadges.tsx b/src/components/home/ReactivateCampaignBadges.tsx index ae64b1a8..a575323d 100644 --- a/src/components/home/ReactivateCampaignBadges.tsx +++ b/src/components/home/ReactivateCampaignBadges.tsx @@ -55,7 +55,7 @@ export function ReactivateCampaignBadges({ }, { id: "hobby", - label: `+${metrics.hobbyTimeHours} hours hobby time by the week`, + label: `${metrics.hobbyTimeHours}+ hobby time this week`, color: "bg-orange-100 text-orange-800 border-orange-200 dark:bg-orange-900 dark:text-orange-100 dark:border-orange-700", }, From c3fcaddf9a559b5d265df769243eca14327d5e67 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 08:57:39 -0700 Subject: [PATCH 05/13] fix: remove unused Badge import and organize imports - Remove unused Badge import from ReactivateCampaignBadges - Organize imports according to linting rules --- src/components/home/ReactivateCampaignBadges.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/home/ReactivateCampaignBadges.tsx b/src/components/home/ReactivateCampaignBadges.tsx index a575323d..8efae62b 100644 --- a/src/components/home/ReactivateCampaignBadges.tsx +++ b/src/components/home/ReactivateCampaignBadges.tsx @@ -1,8 +1,8 @@ "use client"; -import { Badge } from "@/components/ui/badge"; +import { motion, type Variants } from "framer-motion"; + import { cn } from "@/lib/utils"; -import { type Variants, motion } from "framer-motion"; export interface BadgeMetrics { dollarAmount: number; From 3e530dbbcc140251aaa6545b269f481950a96956 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 09:50:39 -0700 Subject: [PATCH 06/13] feat: change 'Review rollout steps' to 'See AI In Action' with smooth scroll - Update microcopy text from 'Review the rollout steps' to 'See AI In Action' - Change anchor link from #live-hero-details to #ai-outreach-demo - Add anchor ID to AI outreach demo section in HeroSessionMonitor - Implement smooth scrolling for anchor links in PersonaCTA component - Update test files to reflect new text - Scrolls smoothly to center the AI outreach demo when clicked --- .../dynamic-hero/src/components/PersonaCTA.tsx | 17 ++++++++++++++++- .../home/heros/HeroSessionMonitor.tsx | 1 + .../__tests__/page.test.tsx | 4 ++-- .../heros/live-dynamic-hero-demo/_config.ts | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/components/dynamic-hero/src/components/PersonaCTA.tsx b/src/components/dynamic-hero/src/components/PersonaCTA.tsx index 8ee3eff9..2c3d18a6 100644 --- a/src/components/dynamic-hero/src/components/PersonaCTA.tsx +++ b/src/components/dynamic-hero/src/components/PersonaCTA.tsx @@ -1,7 +1,7 @@ "use client"; import { AnimatePresence, motion } from "motion/react"; -import type { FC, ReactNode } from "react"; +import type { FC, MouseEvent, ReactNode } from "react"; import { useCallback, useMemo } from "react"; import { z } from "zod"; @@ -111,6 +111,20 @@ const PersonaCTA: FC = ({ if (type === "link") { const [_fullMatch, href, text] = currentMatch; + const isAnchorLink = href.startsWith("#"); + const handleClick = isAnchorLink + ? (e: MouseEvent) => { + e.preventDefault(); + const targetId = href.slice(1); + const targetElement = document.getElementById(targetId); + if (targetElement) { + targetElement.scrollIntoView({ + behavior: "smooth", + block: "center", + }); + } + } + : undefined; elements.push( = ({ > = ({ {/* Session Monitor Carousel */}
diff --git a/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx b/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx index 70e6d0b6..653ab9f9 100644 --- a/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx +++ b/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx @@ -40,7 +40,7 @@ vi.mock("../../live-dynamic-hero-demo/LiveDynamicHeroClient", () => { }, "See How It Works", ), - React.createElement("p", {}, "Review the rollout steps"), + React.createElement("p", {}, "See AI In Action"), ), ); }, @@ -211,7 +211,7 @@ describe("LiveDynamicHeroDemoPage", () => { // Wait for hydrated version to render - findByText already asserts element exists await screen.findByText("Get Started in 1 Click", {}, { timeout: 3000 }); - await screen.findByText(/Review the rollout steps/i, {}, { timeout: 3000 }); + await screen.findByText(/See AI In Action/i, {}, { timeout: 3000 }); }); it("triggers Stripe trial checkout when primary CTA is clicked", async () => { diff --git a/src/components/home/heros/live-dynamic-hero-demo/_config.ts b/src/components/home/heros/live-dynamic-hero-demo/_config.ts index 405fe390..f85d9534 100644 --- a/src/components/home/heros/live-dynamic-hero-demo/_config.ts +++ b/src/components/home/heros/live-dynamic-hero-demo/_config.ts @@ -222,7 +222,7 @@ export const LIVE_SECONDARY_CTA = { }; export const LIVE_MICROCOPY = - 'Review the rollout steps
"People buy from people who make them feel capable and confident." - Dale Carnegie.'; + 'See AI In Action
"People buy from people who make them feel capable and confident." - Dale Carnegie.'; export const LIVE_SOCIAL_PROOF = { ...DEFAULT_HERO_SOCIAL_PROOF, From 0e1ed1f6a42904d32f2bdfb891a949be1b50a518 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 09:51:10 -0700 Subject: [PATCH 07/13] fix: resolve linting issues in test file - Remove unused React import - Fix trailing comma in import statement - Organize imports according to linting rules --- .../heros/live-dynamic-hero-demo/__tests__/page.test.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx b/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx index 653ab9f9..a1b721bf 100644 --- a/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx +++ b/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx @@ -1,9 +1,8 @@ import type { HeroVideoConfig } from "@external/dynamic-hero"; import { fireEvent, render, screen, waitFor } from "@testing-library/react"; -import React from "react"; import type { ReactNode } from "react"; -import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import type { Mock } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import "@testing-library/jest-dom"; const startTrialMock = vi.fn(() => Promise.resolve()); @@ -137,7 +136,7 @@ vi.mock("motion/react", () => ({ })); let LiveDynamicHeroDemoPage: typeof import( - "../../live-dynamic-hero-demo/page", + "../../live-dynamic-hero-demo/page" ).default; beforeAll(async () => { From 48a6c288cc079deb1082b18ce6938b2c6dcabdb2 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 09:51:28 -0700 Subject: [PATCH 08/13] fix: format import statement on single line --- .../home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx b/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx index a1b721bf..c7b62afa 100644 --- a/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx +++ b/src/components/home/heros/live-dynamic-hero-demo/__tests__/page.test.tsx @@ -135,9 +135,7 @@ vi.mock("motion/react", () => ({ useInView: () => true, })); -let LiveDynamicHeroDemoPage: typeof import( - "../../live-dynamic-hero-demo/page" -).default; +let LiveDynamicHeroDemoPage: typeof import("../../live-dynamic-hero-demo/page").default; beforeAll(async () => { Object.defineProperty(window.HTMLElement.prototype, "scrollIntoView", { From b2a1d0d7d91d7f427e541f7ebdcfd394dbc4f10f Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 09:55:39 -0700 Subject: [PATCH 09/13] fix: update anchor link to point to correct AI Outreach Studio section - Change link from #ai-outreach-demo to #ai-outreach-studio - Remove incorrect anchor ID from HeroSessionMonitor - Link now correctly scrolls to CallDemoShowcase section with AI Outreach Studio content - Smooth scrolling already implemented in PersonaCTA component --- src/components/home/heros/HeroSessionMonitor.tsx | 1 - src/components/home/heros/live-dynamic-hero-demo/_config.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/home/heros/HeroSessionMonitor.tsx b/src/components/home/heros/HeroSessionMonitor.tsx index 8006b274..73c01b9e 100644 --- a/src/components/home/heros/HeroSessionMonitor.tsx +++ b/src/components/home/heros/HeroSessionMonitor.tsx @@ -200,7 +200,6 @@ const HeroSessionMonitor: React.FC = ({ {/* Session Monitor Carousel */}
diff --git a/src/components/home/heros/live-dynamic-hero-demo/_config.ts b/src/components/home/heros/live-dynamic-hero-demo/_config.ts index f85d9534..1eb86264 100644 --- a/src/components/home/heros/live-dynamic-hero-demo/_config.ts +++ b/src/components/home/heros/live-dynamic-hero-demo/_config.ts @@ -222,7 +222,7 @@ export const LIVE_SECONDARY_CTA = { }; export const LIVE_MICROCOPY = - 'See AI In Action
"People buy from people who make them feel capable and confident." - Dale Carnegie.'; + 'See AI In Action
"People buy from people who make them feel capable and confident." - Dale Carnegie.'; export const LIVE_SOCIAL_PROOF = { ...DEFAULT_HERO_SOCIAL_PROOF, From e450d68574f47cf171bfdaf80b747d00e135296e Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 10:01:46 -0700 Subject: [PATCH 10/13] docs: add internal documentation for CVE-2025-55182 (React2Shell) - Comprehensive security documentation for critical RCE vulnerability - Includes vulnerability details, remediation steps, and upgrade procedures - Documents current vulnerable state (Next.js 16.0.3) and target (16.0.7) - Provides verification checklist and post-upgrade monitoring guidance - References official Vercel and React security advisories --- _docs/security/CVE-2025-55182-React2Shell.md | 298 +++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 _docs/security/CVE-2025-55182-React2Shell.md diff --git a/_docs/security/CVE-2025-55182-React2Shell.md b/_docs/security/CVE-2025-55182-React2Shell.md new file mode 100644 index 00000000..a1df9357 --- /dev/null +++ b/_docs/security/CVE-2025-55182-React2Shell.md @@ -0,0 +1,298 @@ +# CVE-2025-55182 (React2Shell) - Critical Security Update + +**Status**: 🔴 **CRITICAL - ACTION REQUIRED IMMEDIATELY** +**CVE ID**: CVE-2025-55182 +**Vulnerability Name**: React2Shell +**Severity**: Critical (RCE - Remote Code Execution) +**Date Identified**: December 2025 +**Last Updated**: December 6, 2025 + +--- + +## Executive Summary + +CVE-2025-55182 is a critical remote code execution (RCE) vulnerability affecting React Server Components in Next.js applications. Public exploits are available, and threat actors are actively probing for vulnerable applications. **Immediate upgrade is required.** + +### Current Status + +- **Current Next.js Version**: 16.0.3 (VULNERABLE) +- **Required Version**: 16.0.7 (PATCHED) +- **Upgrade Status**: ⏳ Pending + +--- + +## Vulnerability Details + +### What is React2Shell? + +React2Shell is a critical RCE vulnerability that affects React Server Components (RSC) implementations. The vulnerability allows attackers to execute arbitrary code on the server, potentially leading to: + +- Complete server compromise +- Data exfiltration +- Unauthorized access to internal systems +- Service disruption + +### Affected Versions + +All Next.js versions between **15.0.0** and **16.0.6** are vulnerable: + +| Next.js Version Range | Patched Release | +|----------------------|-----------------| +| 15.0.x | 15.0.5 | +| 15.1.x | 15.1.9 | +| 15.2.x | 15.2.6 | +| 15.3.x | 15.3.6 | +| 15.4.x | 15.4.8 | +| 15.5.x | 15.5.7 | +| **16.0.x** | **16.0.7** ⬅️ **Our Target** | +| 14 canaries after 14.3.0-canary.76 | Downgrade to 14.3.0-canary.76 | +| 15 canaries before 15.6.0-canary.58 | 15.6.0-canary.58 | +| 16 canaries before 16.1.0-canary.12 | 16.1.0-canary.12+ | + +### Threat Landscape + +- ✅ **Public Exploits Available**: Proof-of-concept exploits are publicly available +- ✅ **Active Exploitation**: Threat actors are actively probing for vulnerable applications +- ✅ **Vercel WAF Protection**: Vercel has deployed WAF rules to block known exploit patterns +- ⚠️ **WAF Limitations**: WAF rules cannot guarantee 100% protection against all variants +- 🔴 **Upgrade Required**: Upgrading to a patched version is the **only complete fix** + +--- + +## Remediation Steps + +### Step 1: Verify Current Version + +Check your current Next.js version using one of these methods: + +**Method 1: Browser Console** +```javascript +// Load any page from your app and run: +next.version +``` + +**Method 2: Package.json** +```bash +# Check package.json +grep '"next":' package.json +``` + +**Method 3: Installed Package** +```bash +pnpm list next +``` + +### Step 2: Automated Fix (Recommended First Attempt) + +Vercel has provided an automated fix tool: + +```bash +npx fix-react2shell-next +``` + +This tool will: +- Detect vulnerable Next.js versions +- Automatically upgrade to the patched version +- Update related dependencies if needed + +### Step 3: Manual Upgrade (If Automated Tool Doesn't Work) + +If the automated tool doesn't work or you need manual control: + +1. **Update package.json**: + ```json + { + "dependencies": { + "next": "16.0.7" // Update from 16.0.3 + }, + "devDependencies": { + "@next/bundle-analyzer": "^16.0.7" // Update to match Next.js version + } + } + ``` + +2. **Update dependencies**: + ```bash + pnpm install + ``` + +3. **Verify installation**: + ```bash + pnpm list next + # Should show: next@16.0.7 + ``` + +### Step 4: Verify Upgrade + +1. **Check version in browser**: + - Load any page from your app + - Open browser console + - Run: `next.version` + - Should display: `"16.0.7"` + +2. **Run type checking**: + ```bash + pnpm run typecheck + ``` + +3. **Test build**: + ```bash + pnpm run build + ``` + +4. **Test dev server**: + ```bash + pnpm run dev + ``` + +### Step 5: Test Critical Functionality + +After upgrade, verify these critical features still work: + +- ✅ Dynamic routes (e.g., `/features/[slug]`, `/products/[slug]`) +- ✅ Server components and server actions +- ✅ API routes +- ✅ Middleware functionality +- ✅ Metadata generation +- ✅ Image optimization + +--- + +## Project-Specific Upgrade Details + +### Current Configuration + +- **Package Manager**: pnpm 9.15.9+ +- **Node Version**: >=20.0.0 <21.0.0 +- **Next.js Version**: 16.0.3 → **16.0.7** (target) + +### Related Packages to Update + +- `next`: `16.0.3` → `16.0.7` +- `@next/bundle-analyzer`: `^16.0.3` → `^16.0.7` +- `@next/third-parties`: `^15.4.3` (check compatibility, may need update) + +### Files Modified + +- `package.json` - Update Next.js and related @next package versions +- `pnpm-lock.yaml` - Auto-updated by `pnpm install` + +--- + +## Risk Assessment + +### Upgrade Risk: **LOW** + +This is a **patch version upgrade** (16.0.3 → 16.0.7) within the same major.minor version, which means: + +- ✅ **No Breaking Changes Expected**: Patch versions typically only include bug fixes and security patches +- ✅ **Backward Compatible**: Should not require code changes +- ⚠️ **Testing Required**: Still need to verify critical functionality works + +### Security Risk: **CRITICAL** + +- 🔴 **Public Exploits Available**: Attackers can easily exploit this vulnerability +- 🔴 **Active Probing**: Threat actors are actively scanning for vulnerable apps +- 🔴 **RCE Impact**: Successful exploitation leads to complete server compromise +- 🔴 **Immediate Action Required**: Upgrade cannot be delayed + +--- + +## Deployment Checklist + +- [ ] Run automated fix tool: `npx fix-react2shell-next` +- [ ] Verify Next.js version updated to 16.0.7 +- [ ] Run `pnpm install` to update lockfile +- [ ] Run `pnpm run typecheck` - verify no type errors +- [ ] Run `pnpm run build` - verify build succeeds +- [ ] Run `pnpm run dev` - verify dev server starts +- [ ] Test critical routes (dynamic routes, API routes) +- [ ] Test server components and server actions +- [ ] Verify middleware functionality +- [ ] Check production deployment on Vercel +- [ ] Monitor for any errors or warnings post-deployment + +--- + +## Post-Upgrade Monitoring + +After deployment, monitor for: + +1. **Build Errors**: Check build logs for any new errors +2. **Runtime Errors**: Monitor application logs for unexpected behavior +3. **Performance Issues**: Watch for any performance degradation +4. **Function Timeouts**: Monitor for unusual POST requests or timeout spikes +5. **Unexpected Behavior**: Review application activity for anomalies + +--- + +## Additional Resources + +### Official Documentation + +- **Vercel Security Advisory**: [Blog Post](https://vercel.com/blog) +- **React Security Advisory**: [react.dev blog](https://react.dev/blog) +- **Next.js Security Advisory**: Check Next.js documentation + +### Vercel Platform Protections + +- ✅ **WAF Rules**: Vercel has deployed WAF rules to block known exploit patterns +- ✅ **Deployment Blocking**: Vercel blocks new deployments of vulnerable Next.js versions +- ⚠️ **Not a Replacement**: WAF rules are a defense layer, not a replacement for upgrading + +### Support + +- **Vercel Security Email**: security@vercel.com +- **HackerOne Bounty Program**: $25,000 (high) / $50,000 (critical) for bypass reports + +--- + +## FAQ + +### Q: How do I know if my app was exploited? + +A: Review application logs for: +- Unusual POST requests +- Spikes in function timeouts +- Unexpected behavior or activity +- However, note that function timeouts don't reliably indicate compromise + +### Q: Are Vercel WAF rules enough protection? + +A: No. WAF rules provide an additional layer of defense but cannot guarantee 100% protection against all possible attack variants. **Upgrading to a patched version is the only complete fix.** + +### Q: What if I'm using canary-only features? + +A: You should still prioritize updating. See the Next.js Security Advisory for instructions on updating without disabling canary features. + +### Q: Should I test with publicly available POCs? + +A: **No.** We caution against using publicly available exploits against production environments. Instead, follow the verification steps above. + +### Q: What about other frameworks using React Server Components? + +A: If you use another framework implementing RSC, consult the React Security Advisory on react.dev for framework-specific guidance. + +--- + +## Change Log + +| Date | Action | Details | +|------|--------|---------| +| 2025-12-06 | Document Created | Initial documentation for CVE-2025-55182 | +| 2025-12-06 | Upgrade Plan Created | Plan created for Next.js 16.0.3 → 16.0.7 upgrade | + +--- + +## Related Files + +- `package.json` - Package dependencies +- `pnpm-lock.yaml` - Dependency lockfile +- `.cursor/plans/upgrade_next.js_to_patch_cve-2025-55182_*.plan.md` - Upgrade plan + +--- + +**Last Reviewed**: December 6, 2025 +**Next Review**: After upgrade completion +**Document Owner**: Security Team + From 58ae46583d70c5d18668cb367eb85e588a52397d Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 10:11:03 -0700 Subject: [PATCH 11/13] fix(security): upgrade Next.js to 16.0.7 to patch CVE-2025-55182 (React2Shell) - Upgrade next from 16.0.3 to 16.0.7 (patched version) - Upgrade @next/bundle-analyzer from ^16.0.3 to ^16.0.7 to match - Patches critical RCE vulnerability in React Server Components - Public exploits available - immediate upgrade required - Verified installation: Next.js 16.0.7 confirmed installed - Build tested and passing CVE-2025-55182: Critical remote code execution vulnerability Affected: Next.js 15.0.0 - 16.0.6 Patched: Next.js 16.0.7 See _docs/security/CVE-2025-55182-React2Shell.md for full details --- package.json | 534 ++++++++++++++++++++++++------------------------- pnpm-lock.yaml | 120 +++++------ 2 files changed, 327 insertions(+), 327 deletions(-) diff --git a/package.json b/package.json index b4a1442c..ad8b960a 100644 --- a/package.json +++ b/package.json @@ -1,269 +1,269 @@ { - "name": "dealscale", - "private": true, - "engines": { - "node": ">=20.0.0 <21.0.0", - "pnpm": ">=6.0.0" - }, - "version": "0.0.0", - "scripts": { - "dev": "pnpm run check:env && next dev", - "dev-turbo": "pnpm run check:env && next dev --turbopack", - "build": "pnpm run generate:data && pnpm run check:chunk && pnpm run check:meta && next build", - "typecheck": "tsc --noEmit", - "postbuild": "pnpm run submit:sitemap", - "build:cf": "pnpm exec next-on-pages", - "prepare": "node -e \"const{spawnSync}=require('node:child_process');const CI=!!process.env.CI;const SKIP=process.env.SKIP_HUSKY==='1';const PROD=process.env.NODE_ENV==='production';if(CI||SKIP||PROD){console.log('[prepare] skipping husky');process.exit(0)}const r=spawnSync('pnpm',['exec','husky'],{stdio:'inherit',shell:true});process.exit(r.status??0)\"", - "archive:reports": "pnpm exec tsx tools/reports/archive-lighthouse-report.ts", - "archive:coverage": "pnpm exec tsx tools/reports/archive-vitest-coverage.ts", - "archive:trivy": "pnpm exec tsx tools/security/archive-trivy-report.ts", - "archive:owasp": "pnpm exec tsx tools/security/archive-owasp-report.ts", - "archive:security": "pnpm run archive:trivy && pnpm run archive:owasp", - "start": "pnpm run check:env && next start", - "commit:stage": "git add . && pnpm exec lint-staged", - "check:env": "pnpm exec tsx tools/checks/check-analytics-env.ts", - "check:chunk": "pnpm exec tsx tools/checks/verify-chunk-error-handler.ts", - "check:meta": "pnpm exec tsx tools/checks/verify-meta-description.ts", - "validate:sitemap": "pnpm exec tsx tools/validate-sitemap.ts", - "landing:build": "rm -rf dist && pnpm run check:env && next build && next export -o dist", - "dev:vite": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts vite:dev && pnpm exec vite --config tools/vite-preview/vite.config.ts", - "build:vite": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts vite:build && pnpm exec vite build --config tools/vite-preview/vite.config.ts", - "dev:rspack": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts rspack:dev && pnpm exec rsbuild dev --config tools/rspack-preview/rsbuild.config.ts", - "build:rspack": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts rspack:build && pnpm exec rsbuild build --config tools/rspack-preview/rsbuild.config.ts", - "test": "pnpm run test:vitest", - "test:vitest": "pnpm exec vitest run", - "test:coverage": "pnpm exec vitest run --run", - "security:trivy": "pnpm exec tsx tools/security/run-trivy-scan.ts", - "security:owasp": "pnpm exec tsx tools/security/run-owasp-baseline.ts", - "security:scan": "pnpm run security:trivy && pnpm run security:owasp", - "lint": "pnpm exec biome check --write src", - "format": "biome format --write src", - "clean-build": "rm -rf .next dist .svelte-kit node_modules/.cache && pnpm build", - "export:categories": "node scripts/run-ts.js scripts/strapi/export-categories.ts", - "seed:categories": "node scripts/run-ts.js scripts/strapi/seed-to-strapi.ts", - "seed:generic": "node scripts/run-ts.js scripts/strapi/seed-generic.ts", - "export:generic": "node scripts/run-ts.js scripts/strapi/export-generic.ts", - "export:categories:generic": "pnpm run export:generic -- --module src/data/categories.ts --collection categories", - "seed:categories:generic": "pnpm run seed:generic -- --module src/data/categories.ts --collection categories", - "export:products": "node scripts/run-ts.js scripts/strapi/export-products.ts", - "export:services": "node scripts/run-ts.js scripts/strapi/export-services.ts", - "export:company": "node scripts/run-ts.js scripts/strapi/export-company.ts", - "seed:products": "STRAPI_COLLECTION=products pnpm run seed:generic", - "seed:services": "STRAPI_COLLECTION=services pnpm run seed:generic", - "seed:company": "STRAPI_COLLECTION=company pnpm run seed:generic", - "export:all": "node scripts/run-ts.js scripts/strapi/export-all.ts", - "test:export": "node scripts/run-ts.js scripts/strapi/test-export.ts", - "seed:all": "pnpm run seed:categories && pnpm run seed:products && pnpm run seed:services && pnpm run seed:company", - "submit:sitemap": "node tools/deploy/submit-sitemap.js", - "seo:check": "pnpm exec tsx .github/scripts/seo-check.ts", - "seo:lhci": "bash .github/scripts/seo-lhci.sh", - "contact:test": "bash .github/scripts/contact-test.sh", - "doctor:rspack": "pnpm run build:rspack && pnpm dlx @rsdoctor/cli analyze --profile .rsdoctor/manifest.json", - "perf:lighthouse:local": "pnpm dlx lighthouse@12 http://localhost:3000/ --preset=perf --output=json --output=html --output-path=reports/lighthouse/local", - "perf:lighthouse:prod-local": "lighthouse http://localhost:3000/ --preset=perf --output=json --output=html --output-path=reports/lighthouse/prod", - "perf:lighthouse:prod": "pnpm dlx lighthouse@12 https://dealscale.io/ --preset=perf --throttling.cpuSlowdownMultiplier=4 --throttling.downloadThroughputKbps=1500 --throttling.uploadThroughputKbps=750 --output=json --output=html --output-path=reports/lighthouse/prod", - "perf:lighthouse:local:stable": "pnpm dlx lighthouse@12 http://localhost:3000/ --preset=perf --max-wait-for-load=180000 --chrome-flags=\"--headless=new --disable-dev-shm-usage --no-sandbox --window-size=412,823\" --output=json --output=html --output-path=reports/lighthouse/local-stable", - "perf:lighthouse:desktop:stable": "pnpm dlx lighthouse@12 http://localhost:3000/ --preset=desktop --only-categories=performance --max-wait-for-load=180000 --chrome-flags=\"--headless=new --disable-dev-shm-usage --no-sandbox --window-size=1365,812\" --output=json --output=html --output-path=reports/lighthouse/local-desktop-stable", - "perf:lighthouse:prod:stable": "pnpm dlx lighthouse@12 https://dealscale.io/ --preset=perf --max-wait-for-load=180000 --chrome-flags=\"--headless=new --disable-dev-shm-usage --no-sandbox --window-size=412,823\" --output=json --output=html --output-path=reports/lighthouse/prod-stable", - "build:analyze:head": "ANALYZE=true pnpm next build 2>&1 | head -20", - "generate:data": "pnpm exec tsx tools/data/generate-data-manifest.ts", - "export:landing": "node tools/run-ts.js tools/strapi/export-landing.ts", - "notion:schema": "node scripts/run-ts.js scripts/notion/fetchLinktreeSchema.ts", - "notion:schema:write": "node scripts/run-ts.js scripts/notion/fetchLinktreeSchema.ts --write", - "pixel:server": "node pixel-mock-server/server.js", - "pixel:test": "pnpm run pixel:server & pnpm run test tests/pixel-ingestion.test.ts", - "dev:with-pixel": "pnpm run pixel:server & pnpm run dev" - }, - "lint-staged": { - "**/*.{js,jsx,ts,tsx,json,css,md,html,scss}": [ - "pnpm exec biome format --write" - ] - }, - "pnpm": { - "overrides": { - "restore-cursor>onetime": "5.1.2" - } - }, - "browserslist": { - "production": [ - "chrome >= 90", - "edge >= 90", - "firefox >= 90", - "safari >= 15", - "supports es6-module", - "supports async-functions", - "supports object-values" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "dependencies": { - "@analytics/google-analytics": "^1.1.0", - "@calcom/embed-react": "^1.5.2", - "@faker-js/faker": "^9.9.0", - "@hookform/resolvers": "^3.9.0", - "@mdx-js/react": "^3.1.1", - "@microsoft/clarity": "^1.0.0", - "@next/third-parties": "^15.4.3", - "@notionhq/client": "^5.1.0", - "@plausible-analytics/tracker": "^0.4.3", - "@radix-ui/react-accordion": "^1.2.0", - "@radix-ui/react-alert-dialog": "^1.1.1", - "@radix-ui/react-aspect-ratio": "^1.1.0", - "@radix-ui/react-avatar": "^1.1.0", - "@radix-ui/react-checkbox": "^1.1.1", - "@radix-ui/react-collapsible": "^1.1.0", - "@radix-ui/react-context-menu": "^2.2.1", - "@radix-ui/react-dialog": "^1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-hover-card": "^1.1.1", - "@radix-ui/react-icons": "^1.3.2", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-menubar": "^1.1.1", - "@radix-ui/react-navigation-menu": "^1.2.0", - "@radix-ui/react-popover": "^1.1.1", - "@radix-ui/react-progress": "^1.1.0", - "@radix-ui/react-radio-group": "^1.2.0", - "@radix-ui/react-scroll-area": "^1.1.0", - "@radix-ui/react-select": "^2.1.1", - "@radix-ui/react-separator": "^1.1.0", - "@radix-ui/react-slider": "^1.2.0", - "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-switch": "^1.1.0", - "@radix-ui/react-tabs": "^1.1.0", - "@radix-ui/react-toast": "^1.2.1", - "@radix-ui/react-toggle": "^1.1.0", - "@radix-ui/react-toggle-group": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.4", - "@sendgrid/client": "^8.1.5", - "@sendgrid/mail": "^8.1.5", - "@slack/web-api": "^7.10.0", - "@splinetool/react-spline": "^4.0.0", - "@stitches/react": "^1.2.8", - "@stripe/react-stripe-js": "^3.6.0", - "@stripe/stripe-js": "^7.2.0", - "@supabase/auth-helpers-nextjs": "^0.10.0", - "@supabase/supabase-js": "^2.58.0", - "@tabler/icons-react": "^3.34.0", - "@tailwindcss/typography": "^0.5.15", - "@tanstack/react-query": "^5.72.1", - "@types/leaflet": "^1.9.20", - "@types/papaparse": "^5.5.0", - "@upstash/ratelimit": "^2.0.6", - "@upstash/redis": "^1.35.3", - "analytics": "^0.8.19", - "autoprefixer": "^10.4.20", - "axios": "^1.8.4", - "cheerio": "^1.0.0", - "class-variance-authority": "^0.7.1", - "cloudinary": "^2.6.0", - "clsx": "^2.1.1", - "cmdk": "^1.0.0", - "country-state-city": "^3.2.1", - "date-fns": "^3.6.0", - "dompurify": "^3.2.6", - "embla-carousel-react": "^8.3.0", - "entities": "^6.0.0", - "fast-xml-parser": "^5.3.1", - "framer-motion": "^12.5.0", - "gray-matter": "^4.0.3", - "input-otp": "^1.2.4", - "is-mobile": "^5.0.0", - "js-cookie": "^3.0.5", - "leaflet": "^1.9.4", - "localtunnel": "^2.0.2", - "lottie-react": "^2.4.1", - "lucide-react": "^0.462.0", - "medium-blogs-fetcher": "^1.0.5", - "motion": "^12.19.1", - "next": "16.0.3", - "next-auth": "^4.24.11", - "next-mdx-remote": "^5.0.0", - "next-themes": "^0.3.0", - "ngrok": "5.0.0-beta.2", - "papaparse": "^5.5.3", - "postcss": "^8.4.47", - "react": "^18.3.1", - "react-day-picker": "^8.10.1", - "react-dom": "^18.3.1", - "react-facebook-pixel": "^1.0.4", - "react-hook-form": "^7.53.0", - "react-hot-toast": "^2.5.2", - "react-leaflet": "^5.0.0", - "react-markdown": "^9.1.0", - "react-resizable-panels": "^2.1.3", - "react-social-icons": "^6.24.0", - "react-syntax-highlighter": "^15.6.1", - "react-tweet": "^3.2.2", - "recharts": "^2.12.7", - "rehype-autolink-headings": "^7.1.0", - "rehype-slug": "^6.0.0", - "remark-gfm": "^4.0.1", - "rss-parser": "^3.13.0", - "server-only": "^0.0.1", - "sonner": "^1.5.0", - "stripe": "^18.0.0", - "tailwind-merge": "^2.6.0", - "tailwindcss": "^3.4.11", - "tailwindcss-animate": "^1.0.7", - "uuid": "^11.1.0", - "vaul": "^0.9.3", - "xlsx": "^0.18.5", - "zod": "^3.25.67", - "zustand": "^5.0.6" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "@cloudflare/next-on-pages": "^1.13.16", - "@commitlint/cli": "^20.1.0", - "@commitlint/config-conventional": "^20.0.0", - "@eslint/js": "^9.9.0", - "@lhci/cli": "^0.13.0", - "@next/bundle-analyzer": "^16.0.3", - "@rsbuild/core": "^1.5.6", - "@rsbuild/plugin-react": "^1.0.8", - "@rspack/cli": "^1.0.8", - "@rspack/core": "^1.0.8", - "@svgr/webpack": "^8.1.0", - "@testing-library/jest-dom": "^6.6.3", - "@testing-library/react": "^16.3.0", - "@testing-library/user-event": "^14.6.1", - "@turbo/gen": "2.5.2", - "@types/dompurify": "^3.2.0", - "@types/js-cookie": "^3.0.6", - "@types/node": "^22.5.5", - "@types/node-fetch": "^2.6.12", - "@types/react": "^18.3.21", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.29.1", - "@typescript-eslint/parser": "^8.29.1", - "@vitejs/plugin-react-swc": "^3.9.0", - "@vitest/coverage-v8": "^4.0.8", - "dotenv": "^16.5.0", - "eslint": "^9.9.0", - "eslint-plugin-react-hooks": "^5.1.0-rc.0", - "eslint-plugin-react-refresh": "^0.4.9", - "fast-glob": "^3.3.2", - "globals": "^15.9.0", - "husky": "^9.1.7", - "jsdom": "^25.0.0", - "lint-staged": "^16.2.6", - "lovable-tagger": "^1.1.7", - "node-fetch": "^2.7.0", - "prettier": "^3.5.3", - "prettier-plugin-tailwindcss": "^0.6.11", - "snyk": "^1.1290.0", - "ts-node": "^10.9.2", - "tsconfig-paths": "^4.2.0", - "tsx": "^4.7.0", - "turbo": "^2.5.2", - "typescript": "^5.8.3", - "typescript-eslint": "^8.0.1", - "vite": "^5.4.10", - "vitest": "^2.1.4" - }, - "packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531" + "name": "dealscale", + "private": true, + "engines": { + "node": ">=20.0.0 <21.0.0", + "pnpm": ">=6.0.0" + }, + "version": "0.0.0", + "scripts": { + "dev": "pnpm run check:env && next dev", + "dev-turbo": "pnpm run check:env && next dev --turbopack", + "build": "pnpm run generate:data && pnpm run check:chunk && pnpm run check:meta && next build", + "typecheck": "tsc --noEmit", + "postbuild": "pnpm run submit:sitemap", + "build:cf": "pnpm exec next-on-pages", + "prepare": "node -e \"const{spawnSync}=require('node:child_process');const CI=!!process.env.CI;const SKIP=process.env.SKIP_HUSKY==='1';const PROD=process.env.NODE_ENV==='production';if(CI||SKIP||PROD){console.log('[prepare] skipping husky');process.exit(0)}const r=spawnSync('pnpm',['exec','husky'],{stdio:'inherit',shell:true});process.exit(r.status??0)\"", + "archive:reports": "pnpm exec tsx tools/reports/archive-lighthouse-report.ts", + "archive:coverage": "pnpm exec tsx tools/reports/archive-vitest-coverage.ts", + "archive:trivy": "pnpm exec tsx tools/security/archive-trivy-report.ts", + "archive:owasp": "pnpm exec tsx tools/security/archive-owasp-report.ts", + "archive:security": "pnpm run archive:trivy && pnpm run archive:owasp", + "start": "pnpm run check:env && next start", + "commit:stage": "git add . && pnpm exec lint-staged", + "check:env": "pnpm exec tsx tools/checks/check-analytics-env.ts", + "check:chunk": "pnpm exec tsx tools/checks/verify-chunk-error-handler.ts", + "check:meta": "pnpm exec tsx tools/checks/verify-meta-description.ts", + "validate:sitemap": "pnpm exec tsx tools/validate-sitemap.ts", + "landing:build": "rm -rf dist && pnpm run check:env && next build && next export -o dist", + "dev:vite": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts vite:dev && pnpm exec vite --config tools/vite-preview/vite.config.ts", + "build:vite": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts vite:build && pnpm exec vite build --config tools/vite-preview/vite.config.ts", + "dev:rspack": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts rspack:dev && pnpm exec rsbuild dev --config tools/rspack-preview/rsbuild.config.ts", + "build:rspack": "pnpm exec tsx scripts/bundlers/ensure-preview-flag.ts rspack:build && pnpm exec rsbuild build --config tools/rspack-preview/rsbuild.config.ts", + "test": "pnpm run test:vitest", + "test:vitest": "pnpm exec vitest run", + "test:coverage": "pnpm exec vitest run --run", + "security:trivy": "pnpm exec tsx tools/security/run-trivy-scan.ts", + "security:owasp": "pnpm exec tsx tools/security/run-owasp-baseline.ts", + "security:scan": "pnpm run security:trivy && pnpm run security:owasp", + "lint": "pnpm exec biome check --write src", + "format": "biome format --write src", + "clean-build": "rm -rf .next dist .svelte-kit node_modules/.cache && pnpm build", + "export:categories": "node scripts/run-ts.js scripts/strapi/export-categories.ts", + "seed:categories": "node scripts/run-ts.js scripts/strapi/seed-to-strapi.ts", + "seed:generic": "node scripts/run-ts.js scripts/strapi/seed-generic.ts", + "export:generic": "node scripts/run-ts.js scripts/strapi/export-generic.ts", + "export:categories:generic": "pnpm run export:generic -- --module src/data/categories.ts --collection categories", + "seed:categories:generic": "pnpm run seed:generic -- --module src/data/categories.ts --collection categories", + "export:products": "node scripts/run-ts.js scripts/strapi/export-products.ts", + "export:services": "node scripts/run-ts.js scripts/strapi/export-services.ts", + "export:company": "node scripts/run-ts.js scripts/strapi/export-company.ts", + "seed:products": "STRAPI_COLLECTION=products pnpm run seed:generic", + "seed:services": "STRAPI_COLLECTION=services pnpm run seed:generic", + "seed:company": "STRAPI_COLLECTION=company pnpm run seed:generic", + "export:all": "node scripts/run-ts.js scripts/strapi/export-all.ts", + "test:export": "node scripts/run-ts.js scripts/strapi/test-export.ts", + "seed:all": "pnpm run seed:categories && pnpm run seed:products && pnpm run seed:services && pnpm run seed:company", + "submit:sitemap": "node tools/deploy/submit-sitemap.js", + "seo:check": "pnpm exec tsx .github/scripts/seo-check.ts", + "seo:lhci": "bash .github/scripts/seo-lhci.sh", + "contact:test": "bash .github/scripts/contact-test.sh", + "doctor:rspack": "pnpm run build:rspack && pnpm dlx @rsdoctor/cli analyze --profile .rsdoctor/manifest.json", + "perf:lighthouse:local": "pnpm dlx lighthouse@12 http://localhost:3000/ --preset=perf --output=json --output=html --output-path=reports/lighthouse/local", + "perf:lighthouse:prod-local": "lighthouse http://localhost:3000/ --preset=perf --output=json --output=html --output-path=reports/lighthouse/prod", + "perf:lighthouse:prod": "pnpm dlx lighthouse@12 https://dealscale.io/ --preset=perf --throttling.cpuSlowdownMultiplier=4 --throttling.downloadThroughputKbps=1500 --throttling.uploadThroughputKbps=750 --output=json --output=html --output-path=reports/lighthouse/prod", + "perf:lighthouse:local:stable": "pnpm dlx lighthouse@12 http://localhost:3000/ --preset=perf --max-wait-for-load=180000 --chrome-flags=\"--headless=new --disable-dev-shm-usage --no-sandbox --window-size=412,823\" --output=json --output=html --output-path=reports/lighthouse/local-stable", + "perf:lighthouse:desktop:stable": "pnpm dlx lighthouse@12 http://localhost:3000/ --preset=desktop --only-categories=performance --max-wait-for-load=180000 --chrome-flags=\"--headless=new --disable-dev-shm-usage --no-sandbox --window-size=1365,812\" --output=json --output=html --output-path=reports/lighthouse/local-desktop-stable", + "perf:lighthouse:prod:stable": "pnpm dlx lighthouse@12 https://dealscale.io/ --preset=perf --max-wait-for-load=180000 --chrome-flags=\"--headless=new --disable-dev-shm-usage --no-sandbox --window-size=412,823\" --output=json --output=html --output-path=reports/lighthouse/prod-stable", + "build:analyze:head": "ANALYZE=true pnpm next build 2>&1 | head -20", + "generate:data": "pnpm exec tsx tools/data/generate-data-manifest.ts", + "export:landing": "node tools/run-ts.js tools/strapi/export-landing.ts", + "notion:schema": "node scripts/run-ts.js scripts/notion/fetchLinktreeSchema.ts", + "notion:schema:write": "node scripts/run-ts.js scripts/notion/fetchLinktreeSchema.ts --write", + "pixel:server": "node pixel-mock-server/server.js", + "pixel:test": "pnpm run pixel:server & pnpm run test tests/pixel-ingestion.test.ts", + "dev:with-pixel": "pnpm run pixel:server & pnpm run dev" + }, + "lint-staged": { + "**/*.{js,jsx,ts,tsx,json,css,md,html,scss}": [ + "pnpm exec biome format --write" + ] + }, + "pnpm": { + "overrides": { + "restore-cursor>onetime": "5.1.2" + } + }, + "browserslist": { + "production": [ + "chrome >= 90", + "edge >= 90", + "firefox >= 90", + "safari >= 15", + "supports es6-module", + "supports async-functions", + "supports object-values" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "dependencies": { + "@analytics/google-analytics": "^1.1.0", + "@calcom/embed-react": "^1.5.2", + "@faker-js/faker": "^9.9.0", + "@hookform/resolvers": "^3.9.0", + "@mdx-js/react": "^3.1.1", + "@microsoft/clarity": "^1.0.0", + "@next/third-parties": "^15.4.3", + "@notionhq/client": "^5.1.0", + "@plausible-analytics/tracker": "^0.4.3", + "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-alert-dialog": "^1.1.1", + "@radix-ui/react-aspect-ratio": "^1.1.0", + "@radix-ui/react-avatar": "^1.1.0", + "@radix-ui/react-checkbox": "^1.1.1", + "@radix-ui/react-collapsible": "^1.1.0", + "@radix-ui/react-context-menu": "^2.2.1", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-hover-card": "^1.1.1", + "@radix-ui/react-icons": "^1.3.2", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-menubar": "^1.1.1", + "@radix-ui/react-navigation-menu": "^1.2.0", + "@radix-ui/react-popover": "^1.1.1", + "@radix-ui/react-progress": "^1.1.0", + "@radix-ui/react-radio-group": "^1.2.0", + "@radix-ui/react-scroll-area": "^1.1.0", + "@radix-ui/react-select": "^2.1.1", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slider": "^1.2.0", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-switch": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.0", + "@radix-ui/react-toast": "^1.2.1", + "@radix-ui/react-toggle": "^1.1.0", + "@radix-ui/react-toggle-group": "^1.1.0", + "@radix-ui/react-tooltip": "^1.1.4", + "@sendgrid/client": "^8.1.5", + "@sendgrid/mail": "^8.1.5", + "@slack/web-api": "^7.10.0", + "@splinetool/react-spline": "^4.0.0", + "@stitches/react": "^1.2.8", + "@stripe/react-stripe-js": "^3.6.0", + "@stripe/stripe-js": "^7.2.0", + "@supabase/auth-helpers-nextjs": "^0.10.0", + "@supabase/supabase-js": "^2.58.0", + "@tabler/icons-react": "^3.34.0", + "@tailwindcss/typography": "^0.5.15", + "@tanstack/react-query": "^5.72.1", + "@types/leaflet": "^1.9.20", + "@types/papaparse": "^5.5.0", + "@upstash/ratelimit": "^2.0.6", + "@upstash/redis": "^1.35.3", + "analytics": "^0.8.19", + "autoprefixer": "^10.4.20", + "axios": "^1.8.4", + "cheerio": "^1.0.0", + "class-variance-authority": "^0.7.1", + "cloudinary": "^2.6.0", + "clsx": "^2.1.1", + "cmdk": "^1.0.0", + "country-state-city": "^3.2.1", + "date-fns": "^3.6.0", + "dompurify": "^3.2.6", + "embla-carousel-react": "^8.3.0", + "entities": "^6.0.0", + "fast-xml-parser": "^5.3.1", + "framer-motion": "^12.5.0", + "gray-matter": "^4.0.3", + "input-otp": "^1.2.4", + "is-mobile": "^5.0.0", + "js-cookie": "^3.0.5", + "leaflet": "^1.9.4", + "localtunnel": "^2.0.2", + "lottie-react": "^2.4.1", + "lucide-react": "^0.462.0", + "medium-blogs-fetcher": "^1.0.5", + "motion": "^12.19.1", + "next": "16.0.7", + "next-auth": "^4.24.11", + "next-mdx-remote": "^5.0.0", + "next-themes": "^0.3.0", + "ngrok": "5.0.0-beta.2", + "papaparse": "^5.5.3", + "postcss": "^8.4.47", + "react": "^18.3.1", + "react-day-picker": "^8.10.1", + "react-dom": "^18.3.1", + "react-facebook-pixel": "^1.0.4", + "react-hook-form": "^7.53.0", + "react-hot-toast": "^2.5.2", + "react-leaflet": "^5.0.0", + "react-markdown": "^9.1.0", + "react-resizable-panels": "^2.1.3", + "react-social-icons": "^6.24.0", + "react-syntax-highlighter": "^15.6.1", + "react-tweet": "^3.2.2", + "recharts": "^2.12.7", + "rehype-autolink-headings": "^7.1.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.1", + "rss-parser": "^3.13.0", + "server-only": "^0.0.1", + "sonner": "^1.5.0", + "stripe": "^18.0.0", + "tailwind-merge": "^2.6.0", + "tailwindcss": "^3.4.11", + "tailwindcss-animate": "^1.0.7", + "uuid": "^11.1.0", + "vaul": "^0.9.3", + "xlsx": "^0.18.5", + "zod": "^3.25.67", + "zustand": "^5.0.6" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "@cloudflare/next-on-pages": "^1.13.16", + "@commitlint/cli": "^20.1.0", + "@commitlint/config-conventional": "^20.0.0", + "@eslint/js": "^9.9.0", + "@lhci/cli": "^0.13.0", + "@next/bundle-analyzer": "^16.0.7", + "@rsbuild/core": "^1.5.6", + "@rsbuild/plugin-react": "^1.0.8", + "@rspack/cli": "^1.0.8", + "@rspack/core": "^1.0.8", + "@svgr/webpack": "^8.1.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.0", + "@testing-library/user-event": "^14.6.1", + "@turbo/gen": "2.5.2", + "@types/dompurify": "^3.2.0", + "@types/js-cookie": "^3.0.6", + "@types/node": "^22.5.5", + "@types/node-fetch": "^2.6.12", + "@types/react": "^18.3.21", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^8.29.1", + "@typescript-eslint/parser": "^8.29.1", + "@vitejs/plugin-react-swc": "^3.9.0", + "@vitest/coverage-v8": "^4.0.8", + "dotenv": "^16.5.0", + "eslint": "^9.9.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.9", + "fast-glob": "^3.3.2", + "globals": "^15.9.0", + "husky": "^9.1.7", + "jsdom": "^25.0.0", + "lint-staged": "^16.2.6", + "lovable-tagger": "^1.1.7", + "node-fetch": "^2.7.0", + "prettier": "^3.5.3", + "prettier-plugin-tailwindcss": "^0.6.11", + "snyk": "^1.1290.0", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "tsx": "^4.7.0", + "turbo": "^2.5.2", + "typescript": "^5.8.3", + "typescript-eslint": "^8.0.1", + "vite": "^5.4.10", + "vitest": "^2.1.4" + }, + "packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97802b21..bf15a537 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 1.0.0 '@next/third-parties': specifier: ^15.4.3 - version: 15.4.3(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 15.4.3(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@notionhq/client': specifier: ^5.1.0 version: 5.1.0 @@ -133,7 +133,7 @@ importers: version: 7.10.0 '@splinetool/react-spline': specifier: ^4.0.0 - version: 4.0.0(@splinetool/runtime@1.10.14)(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.0.0(@splinetool/runtime@1.10.14)(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@stitches/react': specifier: ^1.2.8 version: 1.2.8(react@18.3.1) @@ -246,11 +246,11 @@ importers: specifier: ^12.19.1 version: 12.19.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next: - specifier: 16.0.3 - version: 16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 16.0.7 + version: 16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-auth: specifier: ^4.24.11 - version: 4.24.11(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.24.11(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-mdx-remote: specifier: ^5.0.0 version: 5.0.0(@types/react@18.3.23)(react@18.3.1) @@ -356,7 +356,7 @@ importers: version: 1.9.4 '@cloudflare/next-on-pages': specifier: ^1.13.16 - version: 1.13.16(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(wrangler@4.47.0) + version: 1.13.16(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(wrangler@4.47.0) '@commitlint/cli': specifier: ^20.1.0 version: 20.1.0(@types/node@22.15.33)(typescript@5.8.3) @@ -370,8 +370,8 @@ importers: specifier: ^0.13.0 version: 0.13.0 '@next/bundle-analyzer': - specifier: ^16.0.3 - version: 16.0.3 + specifier: ^16.0.7 + version: 16.0.7 '@rsbuild/core': specifier: ^1.5.6 version: 1.6.5 @@ -2305,56 +2305,56 @@ packages: '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} - '@next/bundle-analyzer@16.0.3': - resolution: {integrity: sha512-6Xo8f8/ZXtASfTPa6TH1aUn+xDg9Pkyl1YHVxu+89cVdLH7MnYjxv3rPOfEJ9BwCZCU2q4Flyw5MwltfD2pGbA==} + '@next/bundle-analyzer@16.0.7': + resolution: {integrity: sha512-Um2YA3TSQND+DpqlMDuPZsdjdpcgLzo1wF3zx4zcBCLecS7ucP7O9YFqvHhg000HXTgt++KIjZ9FUwyJSKk1Kw==} - '@next/env@16.0.3': - resolution: {integrity: sha512-IqgtY5Vwsm14mm/nmQaRMmywCU+yyMIYfk3/MHZ2ZTJvwVbBn3usZnjMi1GacrMVzVcAxJShTCpZlPs26EdEjQ==} + '@next/env@16.0.7': + resolution: {integrity: sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw==} - '@next/swc-darwin-arm64@16.0.3': - resolution: {integrity: sha512-MOnbd92+OByu0p6QBAzq1ahVWzF6nyfiH07dQDez4/Nku7G249NjxDVyEfVhz8WkLiOEU+KFVnqtgcsfP2nLXg==} + '@next/swc-darwin-arm64@16.0.7': + resolution: {integrity: sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.0.3': - resolution: {integrity: sha512-i70C4O1VmbTivYdRlk+5lj9xRc2BlK3oUikt3yJeHT1unL4LsNtN7UiOhVanFdc7vDAgZn1tV/9mQwMkWOJvHg==} + '@next/swc-darwin-x64@16.0.7': + resolution: {integrity: sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.0.3': - resolution: {integrity: sha512-O88gCZ95sScwD00mn/AtalyCoykhhlokxH/wi1huFK+rmiP5LAYVs/i2ruk7xST6SuXN4NI5y4Xf5vepb2jf6A==} + '@next/swc-linux-arm64-gnu@16.0.7': + resolution: {integrity: sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@16.0.3': - resolution: {integrity: sha512-CEErFt78S/zYXzFIiv18iQCbRbLgBluS8z1TNDQoyPi8/Jr5qhR3e8XHAIxVxPBjDbEMITprqELVc5KTfFj0gg==} + '@next/swc-linux-arm64-musl@16.0.7': + resolution: {integrity: sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@16.0.3': - resolution: {integrity: sha512-Tc3i+nwt6mQ+Dwzcri/WNDj56iWdycGVh5YwwklleClzPzz7UpfaMw1ci7bLl6GRYMXhWDBfe707EXNjKtiswQ==} + '@next/swc-linux-x64-gnu@16.0.7': + resolution: {integrity: sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@16.0.3': - resolution: {integrity: sha512-zTh03Z/5PBBPdTurgEtr6nY0vI9KR9Ifp/jZCcHlODzwVOEKcKRBtQIGrkc7izFgOMuXDEJBmirwpGqdM/ZixA==} + '@next/swc-linux-x64-musl@16.0.7': + resolution: {integrity: sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@16.0.3': - resolution: {integrity: sha512-Jc1EHxtZovcJcg5zU43X3tuqzl/sS+CmLgjRP28ZT4vk869Ncm2NoF8qSTaL99gh6uOzgM99Shct06pSO6kA6g==} + '@next/swc-win32-arm64-msvc@16.0.7': + resolution: {integrity: sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.0.3': - resolution: {integrity: sha512-N7EJ6zbxgIYpI/sWNzpVKRMbfEGgsWuOIvzkML7wxAAZhPk1Msxuo/JDu1PKjWGrAoOLaZcIX5s+/pF5LIbBBg==} + '@next/swc-win32-x64-msvc@16.0.7': + resolution: {integrity: sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -2729,8 +2729,8 @@ packages: peerDependencies: '@types/react': '*' '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react: 18.3.1 + react-dom: 18.3.1 peerDependenciesMeta: '@types/react': optional: true @@ -6858,8 +6858,8 @@ packages: react: ^16.8 || ^17 || ^18 react-dom: ^16.8 || ^17 || ^18 - next@16.0.3: - resolution: {integrity: sha512-Ka0/iNBblPFcIubTA1Jjh6gvwqfjrGq1Y2MTI5lbjeLIAfmC+p5bQmojpRZqgHHVu5cG4+qdIiwXiBSm/8lZ3w==} + next@16.0.7: + resolution: {integrity: sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A==} engines: {node: '>=20.9.0'} hasBin: true peerDependencies: @@ -9814,7 +9814,7 @@ snapshots: dependencies: mime: 3.0.0 - '@cloudflare/next-on-pages@1.13.16(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(wrangler@4.47.0)': + '@cloudflare/next-on-pages@1.13.16(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(wrangler@4.47.0)': dependencies: acorn: 8.15.0 ast-types: 0.14.2 @@ -9825,7 +9825,7 @@ snapshots: esbuild: 0.15.18 js-yaml: 4.1.0 miniflare: 3.20250718.2 - next: 16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) package-manager-manager: 0.2.0 pcre-to-regexp: 1.1.0 semver: 7.7.3 @@ -10752,42 +10752,42 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@next/bundle-analyzer@16.0.3': + '@next/bundle-analyzer@16.0.7': dependencies: webpack-bundle-analyzer: 4.10.1 transitivePeerDependencies: - bufferutil - utf-8-validate - '@next/env@16.0.3': {} + '@next/env@16.0.7': {} - '@next/swc-darwin-arm64@16.0.3': + '@next/swc-darwin-arm64@16.0.7': optional: true - '@next/swc-darwin-x64@16.0.3': + '@next/swc-darwin-x64@16.0.7': optional: true - '@next/swc-linux-arm64-gnu@16.0.3': + '@next/swc-linux-arm64-gnu@16.0.7': optional: true - '@next/swc-linux-arm64-musl@16.0.3': + '@next/swc-linux-arm64-musl@16.0.7': optional: true - '@next/swc-linux-x64-gnu@16.0.3': + '@next/swc-linux-x64-gnu@16.0.7': optional: true - '@next/swc-linux-x64-musl@16.0.3': + '@next/swc-linux-x64-musl@16.0.7': optional: true - '@next/swc-win32-arm64-msvc@16.0.3': + '@next/swc-win32-arm64-msvc@16.0.7': optional: true - '@next/swc-win32-x64-msvc@16.0.3': + '@next/swc-win32-x64-msvc@16.0.7': optional: true - '@next/third-parties@15.4.3(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@next/third-parties@15.4.3(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: - next: 16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 third-party-capital: 1.0.20 @@ -11873,7 +11873,7 @@ snapshots: '@speed-highlight/core@1.2.12': {} - '@splinetool/react-spline@4.0.0(@splinetool/runtime@1.10.14)(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@splinetool/react-spline@4.0.0(@splinetool/runtime@1.10.14)(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@splinetool/runtime': 1.10.14 blurhash: 2.0.5 @@ -11883,7 +11883,7 @@ snapshots: react-merge-refs: 2.1.1 thumbhash: 0.1.1 optionalDependencies: - next: 16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@splinetool/runtime@1.10.14': dependencies: @@ -15852,13 +15852,13 @@ snapshots: netmask@2.0.2: {} - next-auth@4.24.11(next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-auth@4.24.11(next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.27.6 '@panva/hkdf': 1.2.1 cookie: 0.7.2 jose: 4.15.9 - next: 16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) oauth: 0.9.15 openid-client: 5.7.1 preact: 10.26.9 @@ -15885,9 +15885,9 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@16.0.3(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@16.0.7(@babel/core@7.27.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 16.0.3 + '@next/env': 16.0.7 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001756 postcss: 8.4.31 @@ -15895,14 +15895,14 @@ snapshots: react-dom: 18.3.1(react@18.3.1) styled-jsx: 5.1.6(@babel/core@7.27.4)(react@18.3.1) optionalDependencies: - '@next/swc-darwin-arm64': 16.0.3 - '@next/swc-darwin-x64': 16.0.3 - '@next/swc-linux-arm64-gnu': 16.0.3 - '@next/swc-linux-arm64-musl': 16.0.3 - '@next/swc-linux-x64-gnu': 16.0.3 - '@next/swc-linux-x64-musl': 16.0.3 - '@next/swc-win32-arm64-msvc': 16.0.3 - '@next/swc-win32-x64-msvc': 16.0.3 + '@next/swc-darwin-arm64': 16.0.7 + '@next/swc-darwin-x64': 16.0.7 + '@next/swc-linux-arm64-gnu': 16.0.7 + '@next/swc-linux-arm64-musl': 16.0.7 + '@next/swc-linux-x64-gnu': 16.0.7 + '@next/swc-linux-x64-musl': 16.0.7 + '@next/swc-win32-arm64-msvc': 16.0.7 + '@next/swc-win32-x64-msvc': 16.0.7 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' From 30ee3b37f9a5920bcaa1eb5f5a4b504c55062c3e Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 10:11:18 -0700 Subject: [PATCH 12/13] docs: update CVE-2025-55182 documentation with completed upgrade status --- _docs/security/CVE-2025-55182-React2Shell.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_docs/security/CVE-2025-55182-React2Shell.md b/_docs/security/CVE-2025-55182-React2Shell.md index a1df9357..010ed630 100644 --- a/_docs/security/CVE-2025-55182-React2Shell.md +++ b/_docs/security/CVE-2025-55182-React2Shell.md @@ -15,9 +15,9 @@ CVE-2025-55182 is a critical remote code execution (RCE) vulnerability affecting ### Current Status -- **Current Next.js Version**: 16.0.3 (VULNERABLE) +- **Current Next.js Version**: 16.0.7 (PATCHED) ✅ - **Required Version**: 16.0.7 (PATCHED) -- **Upgrade Status**: ⏳ Pending +- **Upgrade Status**: ✅ **COMPLETED** (December 6, 2025) --- @@ -281,6 +281,8 @@ A: If you use another framework implementing RSC, consult the React Security Adv |------|--------|---------| | 2025-12-06 | Document Created | Initial documentation for CVE-2025-55182 | | 2025-12-06 | Upgrade Plan Created | Plan created for Next.js 16.0.3 → 16.0.7 upgrade | +| 2025-12-06 | Upgrade Completed | Successfully upgraded Next.js from 16.0.3 to 16.0.7 | +| 2025-12-06 | Verification Complete | Confirmed Next.js 16.0.7 installed, build tested | --- From e8b57c1875564b58e15861e50efa8673820fc7b9 Mon Sep 17 00:00:00 2001 From: Codex CLI Date: Sun, 7 Dec 2025 10:11:29 -0700 Subject: [PATCH 13/13] docs: mark CVE-2025-55182 as resolved in documentation header --- _docs/security/CVE-2025-55182-React2Shell.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/security/CVE-2025-55182-React2Shell.md b/_docs/security/CVE-2025-55182-React2Shell.md index 010ed630..809a9a77 100644 --- a/_docs/security/CVE-2025-55182-React2Shell.md +++ b/_docs/security/CVE-2025-55182-React2Shell.md @@ -1,6 +1,6 @@ # CVE-2025-55182 (React2Shell) - Critical Security Update -**Status**: 🔴 **CRITICAL - ACTION REQUIRED IMMEDIATELY** +**Status**: ✅ **RESOLVED - Upgrade Completed (December 6, 2025)** **CVE ID**: CVE-2025-55182 **Vulnerability Name**: React2Shell **Severity**: Critical (RCE - Remote Code Execution)