Skip to content

63 landing page prefetching - #64

Merged
InfinityBowman merged 6 commits into
mainfrom
63-landing-page-prefetching
Dec 16, 2025
Merged

63 landing page prefetching#64
InfinityBowman merged 6 commits into
mainfrom
63-landing-page-prefetching

Conversation

@InfinityBowman

@InfinityBowman InfinityBowman commented Dec 16, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added a Security information page and a Security link in site navigation
    • Implemented link prefetching to improve navigation speed
    • Upgraded product images to WebP for improved loading
  • Chores

    • Added HSTS header for HTTPS requests
    • Updated sitemap with the new Security URL
  • Bug Fixes / Security

    • Enforced filename validation and read-only restrictions for viewer roles on PDF endpoints

✏️ Tip: You can customize this high-level summary in your review settings.

@InfinityBowman InfinityBowman linked an issue Dec 16, 2025 that may be closed by this pull request
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Dec 16, 2025

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
corates 5f78515 Commit Preview URL Dec 16 2025, 04:29 PM

@coderabbitai

coderabbitai Bot commented Dec 16, 2025

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a '/security' landing page with SEO and sitemap updates; introduces PrefetchLink and replaces internal anchor links for prefetching; switches product images to WebP; adds conditional HSTS in middleware; and strengthens PDF routes with filename validation and viewer-role upload/delete restrictions.

Changes

Cohort / File(s) Change Summary
Landing prerender & sitemap
packages/landing/app.config.js, packages/landing/public/sitemap.xml
Added /security to prerender routes and added <url> entry for the security page in the sitemap.
SEO image update
packages/landing/src/components/DefaultSeo.jsx
Replaced product PNG reference with product.webp for Open Graph / Twitter image metadata.
Hero image optimization
packages/landing/src/components/Hero.jsx
Replaced <img> with <picture> including WebP source and a fallback <img>; added width/height, fetchpriority, and decoding attributes.
Navigation -> PrefetchLink
packages/landing/src/components/Navbar.jsx, packages/landing/src/components/Footer.jsx
Replaced internal <a> links with new PrefetchLink across navbar, mobile menu, branding, and footer; added Security link in Footer.
Prefetch component
packages/landing/src/components/PrefetchLink.jsx
New component that prefetches internal hrefs on mouseenter, tracks prefetched URLs in a module-scoped Set, and renders an anchor.
Security route
packages/landing/src/routes/security.jsx
Added new Security route component with SEO metadata and multiple security-focused content sections (Encryption, Auth, Infrastructure, Disclosure, etc.).
HSTS middleware
packages/workers/src/middleware/securityHeaders.js
Added conditional Strict-Transport-Security header for HTTPS requests (max-age=15552000; includeSubDomains), with try/catch around URL parsing.
PDF routes hardening
packages/workers/src/routes/pdfs.js
Added isValidFileName validation for uploads/downloads/deletes, enforced read-only viewer role (403 on POST/DELETE), and extended Content-Disposition with RFC 5987 filename* encoding.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to focus on:
    • packages/landing/src/components/PrefetchLink.jsx: correctness of prefetch logic, URL internal checks, Set deduplication, and event handling props passthrough.
    • packages/workers/src/routes/pdfs.js: filename validation edge cases, ordering of validation vs. storage operations, and role-based permission enforcement.
    • Integration of PrefetchLink in Navbar.jsx / Footer.jsx: ensure accessibility, href semantics, and no broken navigation on client/server render.

Possibly related PRs

  • 63 landing page prefetching #64 — Appears to touch the same landing-site link/prefetch additions, sitemap/app.config changes and the new PrefetchLink component.
  • 49 feedback and support #57 — Modifies landing navigation and prerender/sitemap entries similarly (adds new pages and updates links).

Poem

🐰 I hopped a path to WebP light,
Prefetched links with gentle might,
A security page stands tall and true,
HSTS whispers, PDFs guarded too,
Little rabbit cheers — safe, swift, and bright! 🥕🔒

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title '63 landing page prefetching' is only partially related to the changeset. While prefetching is a significant component, the PR includes multiple additional changes: a new Security route/page, updated SEO metadata, WebP image optimization, sitemap updates, and security header improvements. The title focuses on one feature but misses the broader scope. Consider a more comprehensive title that captures the main features, such as 'Add security page and landing page prefetching' or break into focused PRs per feature.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f192b7c and 5f78515.

📒 Files selected for processing (1)
  • packages/landing/src/routes/security.jsx (1 hunks)

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
packages/workers/src/middleware/securityHeaders.js (1)

14-22: Consider extending HSTS max-age and evaluating preload.

The conditional HSTS header is correctly applied only over HTTPS, which prevents protocol downgrade warnings. However:

  • The 6-month max-age (15552000 seconds) is moderate; production sites typically use 1-2 years (31536000+).
  • The includeSubDomains directive will enforce HTTPS on all subdomains—ensure all subdomains support HTTPS before deploying.
  • Consider adding preload directive if you plan to submit to the HSTS preload list for stronger protection.

Apply this diff if extending to 2 years is appropriate:

-        c.header('Strict-Transport-Security', 'max-age=15552000; includeSubDomains');
+        c.header('Strict-Transport-Security', 'max-age=63072000; includeSubDomains');

Or with preload (only if committing to preload list):

-        c.header('Strict-Transport-Security', 'max-age=15552000; includeSubDomains');
+        c.header('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
packages/landing/src/components/PrefetchLink.jsx (2)

5-13: Improve URL filtering and consider edge cases.

The current implementation has a few limitations:

  1. Line 6: !href.startsWith('/') will reject absolute URLs to the same origin (e.g., https://corates.org/about), even though they could be prefetched. Consider checking against the current origin instead.
  2. Line 6: Hash-only URLs like #features will pass the filter and create unnecessary prefetch links. Add validation to skip fragment-only navigation.
  3. No SSR guard: If this runs during SSR, document will be undefined. Consider wrapping in an isServer check or using typeof document !== 'undefined'.

Here's an improved version:

 function prefetch(href) {
-  if (prefetched.has(href) || !href.startsWith('/')) return;
+  // Skip if already prefetched, external, hash-only, or SSR
+  if (
+    prefetched.has(href) ||
+    !href ||
+    href.startsWith('#') ||
+    href.startsWith('http://') ||
+    href.startsWith('https://') ||
+    typeof document === 'undefined'
+  ) {
+    return;
+  }
   prefetched.add(href);
 
   const link = document.createElement('link');
   link.rel = 'prefetch';
   link.href = href;
+  link.as = 'document';
   document.head.appendChild(link);
 }

Alternatively, for same-origin absolute URLs:

function prefetch(href) {
  if (
    prefetched.has(href) ||
    !href ||
    href.startsWith('#') ||
    typeof document === 'undefined'
  ) {
    return;
  }
  
  // Check if URL is same-origin
  try {
    const url = new URL(href, window.location.origin);
    if (url.origin !== window.location.origin) return;
  } catch {
    // Invalid URL, skip
    return;
  }
  
  prefetched.add(href);
  
  const link = document.createElement('link');
  link.rel = 'prefetch';
  link.href = href;
  link.as = 'document';
  document.head.appendChild(link);
}

15-29: Consider extracting hover logic and handling focus.

The component correctly uses splitProps to avoid breaking reactivity. A few optional enhancements:

  1. Focus prefetching: Consider adding onFocus in addition to onMouseEnter to support keyboard navigation and improve accessibility.
  2. Touch devices: onMouseEnter won't fire on touch devices. Consider adding onTouchStart for mobile optimization.

Example with focus and touch support:

 export default function PrefetchLink(props) {
   const [local, others] = splitProps(props, ['href', 'children', 'class']);
 
-  const handleMouseEnter = () => {
+  const handlePrefetch = () => {
     if (local.href) {
       prefetch(local.href);
     }
   };
 
   return (
-    <a href={local.href} class={local.class} onMouseEnter={handleMouseEnter} {...others}>
+    <a 
+      href={local.href} 
+      class={local.class} 
+      onMouseEnter={handlePrefetch}
+      onFocus={handlePrefetch}
+      onTouchStart={handlePrefetch}
+      {...others}
+    >
       {local.children}
     </a>
   );
 }
packages/workers/src/routes/pdfs.js (1)

54-61: Consider additional edge case validations.

The validation function effectively prevents path traversal and header injection. However, consider adding checks for edge cases:

  • Reject . and .. as filenames
  • Reject leading/trailing whitespace
  • Consider checking for null bytes (\0)

Apply this diff to enhance the validation:

 function isValidFileName(fileName) {
   if (!fileName) return false;
+  const trimmed = fileName.trim();
+  if (trimmed !== fileName) return false;
+  if (trimmed === '.' || trimmed === '..') return false;
   if (fileName.length > 200) return false;
   if (/[\\/]/.test(fileName)) return false;
   if (/\p{C}/u.test(fileName)) return false;
   if (fileName.includes('"')) return false;
+  if (fileName.includes('\0')) return false;
   return true;
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abe90ef and f192b7c.

📒 Files selected for processing (10)
  • packages/landing/app.config.js (1 hunks)
  • packages/landing/public/sitemap.xml (1 hunks)
  • packages/landing/src/components/DefaultSeo.jsx (1 hunks)
  • packages/landing/src/components/Footer.jsx (5 hunks)
  • packages/landing/src/components/Hero.jsx (1 hunks)
  • packages/landing/src/components/Navbar.jsx (4 hunks)
  • packages/landing/src/components/PrefetchLink.jsx (1 hunks)
  • packages/landing/src/routes/security.jsx (1 hunks)
  • packages/workers/src/middleware/securityHeaders.js (1 hunks)
  • packages/workers/src/routes/pdfs.js (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

Files:

  • packages/workers/src/middleware/securityHeaders.js
  • packages/landing/src/components/PrefetchLink.jsx
  • packages/landing/app.config.js
  • packages/landing/src/routes/security.jsx
  • packages/landing/src/components/Footer.jsx
  • packages/landing/src/components/DefaultSeo.jsx
  • packages/landing/src/components/Navbar.jsx
  • packages/landing/src/components/Hero.jsx
  • packages/workers/src/routes/pdfs.js
packages/{web,landing}/src/**/*.{jsx,tsx,css}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use responsive design principles for UI components

Files:

  • packages/landing/src/components/PrefetchLink.jsx
  • packages/landing/src/routes/security.jsx
  • packages/landing/src/components/Footer.jsx
  • packages/landing/src/components/DefaultSeo.jsx
  • packages/landing/src/components/Navbar.jsx
  • packages/landing/src/components/Hero.jsx
🧠 Learnings (10)
📚 Learning: 2025-12-16T05:05:58.178Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-16T05:05:58.178Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Applied to files:

  • packages/landing/src/components/PrefetchLink.jsx
  • packages/landing/src/components/Navbar.jsx
📚 Learning: 2025-12-16T05:05:58.178Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-16T05:05:58.178Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Do not destructure props in SolidJS components as it breaks reactivity. Instead access props directly from the props object or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/landing/src/components/PrefetchLink.jsx
  • packages/landing/src/routes/security.jsx
  • packages/landing/src/components/Hero.jsx
📚 Learning: 2025-12-16T00:29:26.670Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-16T00:29:26.670Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx,js,ts} : Create reusable logic in 'primitives' (hooks) that can be shared across components to keep components clean and focused on rendering

Applied to files:

  • packages/landing/src/components/PrefetchLink.jsx
  • packages/landing/src/components/Navbar.jsx
📚 Learning: 2025-12-16T00:29:26.670Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-16T00:29:26.670Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : In SolidJS components, do not destructure props as it breaks reactivity - instead access props directly from the props object, or wrap them in a function to ensure they are always up-to-date

Applied to files:

  • packages/landing/src/components/PrefetchLink.jsx
📚 Learning: 2025-12-16T05:05:58.178Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-16T05:05:58.178Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Use `createMemo` for derived values based on props or state to ensure reactive updates

Applied to files:

  • packages/landing/src/components/PrefetchLink.jsx
  • packages/landing/src/components/Navbar.jsx
📚 Learning: 2025-12-16T00:29:26.670Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-16T00:29:26.670Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Do NOT prop-drill application state in SolidJS components - shared or cross-feature state must live in external stores under `packages/web/src/stores/` or relative to the component file

Applied to files:

  • packages/landing/src/routes/security.jsx
📚 Learning: 2025-12-16T05:05:58.178Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-16T05:05:58.178Z
Learning: Applies to packages/{web,landing}/src/**/*.{jsx,tsx,css} : Use responsive design principles for UI components

Applied to files:

  • packages/landing/src/components/Navbar.jsx
  • packages/landing/src/components/Hero.jsx
📚 Learning: 2025-12-16T00:29:26.670Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-16T00:29:26.670Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Use responsive design principles for UI components

Applied to files:

  • packages/landing/src/components/Navbar.jsx
  • packages/landing/src/components/Hero.jsx
📚 Learning: 2025-12-16T00:29:26.670Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursorrules:0-0
Timestamp: 2025-12-16T00:29:26.670Z
Learning: Applies to packages/web/src/components/**/*.{jsx,tsx} : Components should be lean and focused - do not implement business logic in components; move that into stores, utilities, or primitives

Applied to files:

  • packages/landing/src/components/Navbar.jsx
📚 Learning: 2025-12-16T05:05:58.178Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-16T05:05:58.178Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Use Zag.js for UI components and design system

Applied to files:

  • packages/landing/src/components/Navbar.jsx
  • packages/landing/src/components/Hero.jsx
🧬 Code graph analysis (5)
packages/workers/src/middleware/securityHeaders.js (1)
packages/workers/src/index.js (2)
  • url (131-131)
  • c (198-198)
packages/landing/src/routes/security.jsx (2)
packages/landing/src/components/Navbar.jsx (1)
  • Navbar (7-112)
packages/landing/src/components/Footer.jsx (1)
  • Footer (4-130)
packages/landing/src/components/Footer.jsx (1)
packages/landing/src/components/PrefetchLink.jsx (1)
  • PrefetchLink (15-29)
packages/landing/src/components/Navbar.jsx (1)
packages/landing/src/components/PrefetchLink.jsx (1)
  • PrefetchLink (15-29)
packages/workers/src/routes/pdfs.js (1)
packages/workers/src/config/constants.js (3)
  • createErrorResponse (125-134)
  • ERROR_CODES (73-117)
  • ERROR_CODES (73-117)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (20)
packages/landing/src/components/DefaultSeo.jsx (1)

5-5: LGTM! WebP format improves social card performance.

The switch from PNG to WebP for Open Graph and Twitter card images should reduce file size while maintaining quality.

packages/landing/app.config.js (1)

14-14: LGTM! Security route added for prerendering.

The addition of '/security' to the prerender routes aligns with the new security page and sitemap updates.

packages/landing/public/sitemap.xml (1)

18-20: LGTM! Sitemap includes new security page.

The addition of the security URL entry aligns with the route and prerender configuration.

packages/landing/src/components/Hero.jsx (1)

64-76: LGTM! Progressive image enhancement with WebP.

The <picture> element with WebP source and PNG fallback provides optimal loading performance while maintaining compatibility. The fetchpriority='high' is appropriate for this hero/LCP image, and explicit dimensions prevent layout shift.

packages/landing/src/components/Navbar.jsx (4)

5-5: LGTM! PrefetchLink imported for navigation optimization.


27-40: LGTM! Logo link upgraded to PrefetchLink.

The logo link now benefits from prefetch-on-hover behavior for the home route.


43-48: LGTM! Navigation links upgraded to PrefetchLink.

Internal navigation links now prefetch on hover, improving perceived navigation speed.


137-144: LGTM! Mobile menu links upgraded to PrefetchLink.

Mobile navigation now benefits from prefetching, with proper onClick handling to close the menu.

packages/landing/src/components/Footer.jsx (3)

2-2: LGTM! PrefetchLink imported for footer navigation.


13-15: LGTM! Internal footer links upgraded to PrefetchLink.

All internal navigation links (brand, pricing, features, about, contact, privacy, terms) now use PrefetchLink for prefetch-on-hover optimization.

Also applies to: 26-31, 34-39, 58-63, 66-71, 81-86, 89-94


96-102: LGTM! Security link added to Legal section.

The new security link is correctly integrated with PrefetchLink and aligns with the new /security route.

packages/landing/src/routes/security.jsx (7)

1-6: LGTM!

The imports are well-organized and properly use path aliases per coding guidelines. All necessary dependencies for SEO metadata, icons, and layout components are imported.


7-12: LGTM!

The component setup follows SolidJS best practices and properly constructs SEO metadata using config values. Modern ES6+ syntax is used appropriately.


13-23: LGTM!

Comprehensive SEO metadata implementation with proper canonical URL, Open Graph, and Twitter card tags. This aligns well with the PR's sitemap and SEO updates.


40-123: LGTM!

The security features section uses a consistent, well-structured card layout with appropriate semantic HTML and icons. The responsive design principles with Tailwind utility classes align with the coding guidelines.


125-163: LGTM!

The responsible disclosure section is comprehensive and professional, with clear guidelines for security researchers. Good use of semantic HTML and appropriate amber color scheme to signal the importance of vulnerability reporting.


165-186: LGTM!

The security questions section maintains consistency with the overall page structure and provides clear contact information for general security inquiries.


189-195: LGTM!

The page structure properly wraps content with Navbar and Footer components, using a flex layout to ensure proper footer positioning. The component closure is clean and correct.

packages/workers/src/routes/pdfs.js (2)

98-103: LGTM! Proper authorization guard.

The permission check correctly enforces read-only access for viewers, preventing unauthorized uploads. The early placement before content processing is efficient.


249-251: LGTM! Proper RFC 5987 encoding for international characters.

The Content-Disposition header now correctly supports Unicode filenames using RFC 5987 encoding while maintaining backwards compatibility with the traditional filename parameter. The validation ensures no header injection risk.

Comment thread packages/landing/src/routes/security.jsx Outdated
Comment on lines +170 to +178
if (!isValidFileName(fileName)) {
return c.json(
createErrorResponse(
ERROR_CODES.MISSING_FIELD,
'Invalid file name. Avoid quotes, slashes, control characters, and very long names.',
),
400,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Consider using a more semantically appropriate error code.

The validation logic and placement are correct. However, ERROR_CODES.MISSING_FIELD is semantically incorrect here since the field is present but invalid. Consider using ERROR_CODES.FILE_INVALID_TYPE or requesting a new error code for invalid filenames.

     if (!isValidFileName(fileName)) {
       return c.json(
         createErrorResponse(
-          ERROR_CODES.MISSING_FIELD,
+          ERROR_CODES.FILE_INVALID_TYPE,
           'Invalid file name. Avoid quotes, slashes, control characters, and very long names.',
         ),
         400,
       );
     }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/workers/src/routes/pdfs.js around lines 170 to 178, the handler
returns ERROR_CODES.MISSING_FIELD for an invalid filename which is semantically
wrong; change the returned error code to ERROR_CODES.FILE_INVALID_TYPE if that
constant exists, otherwise add a new error code (e.g.,
ERROR_CODES.INVALID_FILE_NAME) to the ERROR_CODES enum/definition and return
that here, keeping the existing message and 400 status.

Comment on lines +233 to +235
if (!isValidFileName(fileName)) {
return c.json(createErrorResponse(ERROR_CODES.MISSING_FIELD, 'Invalid file name'), 400);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Same error code semantics issue as in upload.

The validation correctly prevents path traversal attempts. However, the same error code semantics issue applies here—use a more appropriate code than ERROR_CODES.MISSING_FIELD.

   if (!isValidFileName(fileName)) {
-    return c.json(createErrorResponse(ERROR_CODES.MISSING_FIELD, 'Invalid file name'), 400);
+    return c.json(createErrorResponse(ERROR_CODES.FILE_INVALID_TYPE, 'Invalid file name'), 400);
   }
🤖 Prompt for AI Agents
In packages/workers/src/routes/pdfs.js around lines 233 to 235, the handler
returns ERROR_CODES.MISSING_FIELD when isValidFileName fails; change the
returned error code to one that correctly represents invalid/unsafe input (e.g.,
ERROR_CODES.INVALID_FIELD or ERROR_CODES.INVALID_INPUT) and update the JSON
response accordingly — if that constant doesn't exist, add a clearly named error
code constant and use it here so the semantics reflect an invalid filename/path
traversal attempt rather than a missing field.

Comment on lines +281 to +283
if (!isValidFileName(fileName)) {
return c.json(createErrorResponse(ERROR_CODES.MISSING_FIELD, 'Invalid file name'), 400);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Same error code semantics issue as in other routes.

The validation is correctly placed and prevents path traversal in delete operations. Apply the same error code fix as suggested for upload and download routes.

   if (!isValidFileName(fileName)) {
-    return c.json(createErrorResponse(ERROR_CODES.MISSING_FIELD, 'Invalid file name'), 400);
+    return c.json(createErrorResponse(ERROR_CODES.FILE_INVALID_TYPE, 'Invalid file name'), 400);
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!isValidFileName(fileName)) {
return c.json(createErrorResponse(ERROR_CODES.MISSING_FIELD, 'Invalid file name'), 400);
}
if (!isValidFileName(fileName)) {
return c.json(createErrorResponse(ERROR_CODES.FILE_INVALID_TYPE, 'Invalid file name'), 400);
}
🤖 Prompt for AI Agents
In packages/workers/src/routes/pdfs.js around lines 281 to 283, the validation
branch returns ERROR_CODES.MISSING_FIELD for an invalid file name; update it to
use the correct semantics used in upload/download routes by returning
ERROR_CODES.INVALID_FIELD (and keep the 400 status and current message), so the
error code reflects an invalid field rather than a missing one.

@InfinityBowman
InfinityBowman merged commit 2392857 into main Dec 16, 2025
1 of 2 checks passed
@InfinityBowman
InfinityBowman deleted the 63-landing-page-prefetching branch December 16, 2025 16:27
InfinityBowman added a commit that referenced this pull request Dec 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Landing page prefetching

2 participants