Skip to content

Commit 5beee22

Browse files
catomeanclaude
andcommitted
fix(deps): patch fast-xml-parser vulnerability and improve Link usage
Security fixes: - Add npm override for fast-xml-parser@^5.3.4 to fix RangeError DoS - Update @aws-sdk/client-ses to 3.980.0 - Reduces vulnerabilities from 25 to 8 (fixed 17 high severity) Code improvements (prep for future Next.js 15): - Replace <a> tags with <Link> components for internal navigation - Create ConsultationFormLoader client wrapper for dynamic imports - Use direct Analytics import instead of dynamic with ssr:false - Add eslint-disable for global-error.tsx (intentional <a> usage) Remaining vulnerabilities (require breaking changes): - 7 moderate: eslint circular reference stack overflow - 1 high: Next.js DoS (specific conditions, low practical risk) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 41bd8bf commit 5beee22

10 files changed

Lines changed: 2028 additions & 2022 deletions

File tree

app/enterprise/page.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { type Metadata } from 'next';
22
import Link from 'next/link';
3-
import nextDynamic from 'next/dynamic';
4-
5-
const ConsultationForm = nextDynamic(() => import('@/components/ConsultationForm'), {
6-
loading: () => <div className="min-h-[200px] flex items-center justify-center">Loading...</div>,
7-
ssr: false,
8-
});
3+
import { ConsultationFormLoader } from '@/components/ConsultationFormLoader';
94

105
export const metadata: Metadata = {
116
title: 'Enterprise | Botsmann',
@@ -335,7 +330,7 @@ export default function EnterprisePage() {
335330
</div>
336331

337332
<div className="bg-white rounded-2xl p-8 shadow-xl border border-gray-100 max-w-xl mx-auto">
338-
<ConsultationForm />
333+
<ConsultationFormLoader />
339334
</div>
340335
</section>
341336
</main>

app/error.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client';
22

33
import { useEffect } from 'react';
4+
import Link from 'next/link';
45

56
interface ErrorProps {
67
error: Error & { digest?: string };
@@ -43,19 +44,15 @@ export default function Error({ error, reset }: ErrorProps) {
4344
</div>
4445
</div>
4546

46-
<h2 className="text-2xl font-bold text-gray-900 mb-2">
47-
Something went wrong
48-
</h2>
47+
<h2 className="text-2xl font-bold text-gray-900 mb-2">Something went wrong</h2>
4948

5049
<p className="text-gray-600 mb-6">
5150
An unexpected error occurred. Don&apos;t worry, your data is safe.
5251
</p>
5352

5453
{process.env.NODE_ENV === 'development' && error.message && (
5554
<div className="mb-6 p-4 bg-gray-100 rounded-lg text-left">
56-
<p className="text-sm font-mono text-gray-700 break-all">
57-
{error.message}
58-
</p>
55+
<p className="text-sm font-mono text-gray-700 break-all">{error.message}</p>
5956
</div>
6057
)}
6158

@@ -66,12 +63,12 @@ export default function Error({ error, reset }: ErrorProps) {
6663
>
6764
Try again
6865
</button>
69-
<a
66+
<Link
7067
href="/"
7168
className="px-6 py-3 bg-gray-100 text-gray-700 font-medium rounded-lg hover:bg-gray-200 transition-colors"
7269
>
7370
Go home
74-
</a>
71+
</Link>
7572
</div>
7673
</div>
7774
</div>

app/global-error.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use client';
22

3+
/* eslint-disable @next/next/no-html-link-for-pages */
4+
35
/**
46
* Global Error Boundary
57
*
@@ -36,23 +38,17 @@ export default function GlobalError({
3638
</div>
3739
</div>
3840

39-
<h1 className="text-3xl font-bold text-gray-900 mb-2">
40-
Application Error
41-
</h1>
41+
<h1 className="text-3xl font-bold text-gray-900 mb-2">Application Error</h1>
4242

4343
<p className="text-gray-600 mb-6">
4444
We encountered a critical error. Our team has been notified.
4545
</p>
4646

4747
{process.env.NODE_ENV === 'development' && error.message && (
4848
<div className="mb-6 p-4 bg-gray-100 rounded-lg text-left">
49-
<p className="text-sm font-mono text-gray-700 break-all">
50-
{error.message}
51-
</p>
49+
<p className="text-sm font-mono text-gray-700 break-all">{error.message}</p>
5250
{error.digest && (
53-
<p className="text-xs text-gray-500 mt-2">
54-
Error ID: {error.digest}
55-
</p>
51+
<p className="text-xs text-gray-500 mt-2">Error ID: {error.digest}</p>
5652
)}
5753
</div>
5854
)}

app/layout.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@ import { Footer } from '@/components/Footer';
33
import { Providers } from '@/components/Providers';
44
import { site } from '@/lib/site';
55
import './globals.css';
6-
import dynamic from 'next/dynamic';
76
import { Toaster } from 'sonner';
8-
9-
const Analytics = dynamic(
10-
() => import('@vercel/analytics/react').then((m) => m.Analytics).catch(() => () => null),
11-
{ ssr: false },
12-
);
7+
import { Analytics } from '@vercel/analytics/react';
138

149
export const metadata = {
1510
title: `${site.name} - ${site.tagline}`,

app/professionals/page.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type Metadata } from 'next';
2+
import Link from 'next/link';
23
import { professionals } from '@/data/professionals';
34
import { ProfessionalCard } from '@/components/shared/ProfessionalCard';
45

@@ -65,20 +66,20 @@ export default function ProfessionalsPage() {
6566
expert if needed.
6667
</p>
6768
<div className="flex flex-col sm:flex-row justify-center gap-4">
68-
<a
69+
<Link
6970
href="/professionals/legal"
7071
className="inline-flex items-center justify-center gap-2 bg-blue-600 text-white px-6 py-3 rounded-xl font-semibold hover:bg-blue-700 transition-colors"
7172
>
7273
<span>⚖️</span>
7374
Start with Legal
74-
</a>
75-
<a
75+
</Link>
76+
<Link
7677
href="/professionals/health"
7778
className="inline-flex items-center justify-center gap-2 bg-green-600 text-white px-6 py-3 rounded-xl font-semibold hover:bg-green-700 transition-colors"
7879
>
7980
<span>⚕️</span>
8081
Start with Health
81-
</a>
82+
</Link>
8283
</div>
8384
</div>
8485
</section>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use client';
2+
3+
import dynamic from 'next/dynamic';
4+
5+
const ConsultationForm = dynamic(() => import('@/components/ConsultationForm'), {
6+
loading: () => <div className="min-h-[200px] flex items-center justify-center">Loading...</div>,
7+
ssr: false,
8+
});
9+
10+
export function ConsultationFormLoader() {
11+
return <ConsultationForm />;
12+
}

components/documents/AddToBotModal.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client';
22

33
import { useState, useEffect } from 'react';
4+
import Link from 'next/link';
45
import { documentToasts } from '@/lib/toast';
56
import { LoadingSpinner } from '@/components/shared/LoadingSpinner';
67

@@ -128,12 +129,12 @@ export const AddToBotModal = ({
128129
<div className="text-center py-8">
129130
<span className="text-4xl mb-3 block">🤖</span>
130131
<p className="text-gray-600 mb-4">No bots yet</p>
131-
<a
132+
<Link
132133
href="/bots/create"
133134
className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors text-sm"
134135
>
135136
Create your first bot
136-
</a>
137+
</Link>
137138
</div>
138139
) : (
139140
<div className="space-y-2">
@@ -183,9 +184,12 @@ export const AddToBotModal = ({
183184

184185
{/* Footer */}
185186
<div className="flex items-center justify-between p-4 border-t border-gray-200 bg-gray-50">
186-
<a href="/bots/create" className="text-sm text-blue-600 hover:text-blue-700 font-medium">
187+
<Link
188+
href="/bots/create"
189+
className="text-sm text-blue-600 hover:text-blue-700 font-medium"
190+
>
187191
+ Create new bot
188-
</a>
192+
</Link>
189193
<button
190194
onClick={onClose}
191195
className="px-4 py-2 text-gray-700 hover:bg-gray-200 rounded-lg transition-colors text-sm font-medium"

components/shared/BotNotFoundFallback.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type FC } from 'react';
2+
import Link from 'next/link';
23

34
interface BotNotFoundFallbackProps {
45
botName?: string;
@@ -14,7 +15,7 @@ export const BotNotFoundFallback: FC<BotNotFoundFallbackProps> = ({ botName = 'B
1415
<div className="text-6xl mb-4">🤖</div>
1516
<h1 className="text-2xl font-semibold text-gray-900 mb-2">{botName} Not Found</h1>
1617
<p className="text-gray-600 mb-6">The bot configuration could not be loaded.</p>
17-
<a
18+
<Link
1819
href="/bots"
1920
className="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
2021
>
@@ -27,7 +28,7 @@ export const BotNotFoundFallback: FC<BotNotFoundFallbackProps> = ({ botName = 'B
2728
/>
2829
</svg>
2930
Back to All Bots
30-
</a>
31+
</Link>
3132
</div>
3233
</div>
3334
);

0 commit comments

Comments
 (0)