Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/docs/exosphere/state-manager-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The Exosphere state manager is the core backend service that handles workflow ex
-e MONGO_DATABASE_NAME="your-database-name" \
-e STATE_MANAGER_SECRET="your-secret-key" \
-e SECRETS_ENCRYPTION_KEY="your-base64-encoded-encryption-key" \
ghcr.io/exospherehost/state-manager:latest
ghcr.io/exospherehost/exosphere-state-manager:latest
```

2. **Verify the service is running**:
Expand Down
2 changes: 2 additions & 0 deletions landing-page/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { darkerGrotesque, pattanakarn } from '../lib/fonts';
import "./globals.css";
import { GoogleAnalytics } from '@next/third-parties/google'
import RB2BLoader from '../components/RB2BLoader';

export const metadata: Metadata = {
title: "Exosphere | Async AI Workflows at Scale",
Expand Down Expand Up @@ -73,6 +74,7 @@ export default function RootLayout({
>
{children}
<GoogleAnalytics gaId="G-XY9H2PN0ZX" />
<RB2BLoader />
</body>
</html>
);
Expand Down
21 changes: 21 additions & 0 deletions landing-page/src/components/RB2BLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import { usePathname } from 'next/navigation';
import { useEffect } from 'react';

export default function RB2BLoader() {
const pathname = usePathname();

useEffect(() => {
const existing = document.getElementById('rb2b-script');
if (existing) existing.remove();

const script = document.createElement('script');
script.id = 'rb2b-script';
script.src = `https://ddwl4m2hdecbv.cloudfront.net/b/${process.env.NEXT_PUBLIC_RB2B_ID}/${process.env.NEXT_PUBLIC_RB2B_ID}.js.gz`;
script.async = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

high

For security, when loading third-party scripts, it's crucial to use Subresource Integrity (SRI). This ensures that the file your users fetch has not been tampered with. You should add an integrity hash and crossOrigin attribute to the script tag. You will need to generate the hash for the specific version of the script you are loading.

    script.integrity = "sha256-your-hash-here"; // Replace with the actual script hash
    script.crossOrigin = "anonymous";
    script.async = true;

document.body.appendChild(script);
}, [pathname]);
Comment on lines +9 to +18
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This useEffect hook can be made more robust.

  1. Missing Environment Variable Check: The component doesn't check if process.env.NEXT_PUBLIC_RB2B_ID is set. If it's missing, the script src will be invalid, leading to failed requests. It's better to handle this case explicitly by not attempting to load the script.
  2. Missing Cleanup Function: The effect adds a script to document.body but doesn't clean it up when the component unmounts. While this component may not unmount in its current usage, it's a good practice to return a cleanup function from useEffect to handle side effects properly.

Also, consider if re-adding the script on every path change is necessary. If the tracking library supports it, it's more performant to load the script once and call a page-view tracking function on navigation.

  useEffect(() => {
    const rb2bId = process.env.NEXT_PUBLIC_RB2B_ID;
    if (!rb2bId) {
      if (process.env.NODE_ENV === 'development') {
        console.warn('RB2B tracking ID (NEXT_PUBLIC_RB2B_ID) is not configured.');
      }
      return;
    }

    const existing = document.getElementById('rb2b-script');
    if (existing) {
      existing.remove();
    }

    const script = document.createElement('script');
    script.id = 'rb2b-script';
    script.src = `https://ddwl4m2hdecbv.cloudfront.net/b/${rb2bId}/${rb2bId}.js.gz`;
    script.async = true;
    document.body.appendChild(script);

    return () => {
      const scriptElement = document.getElementById('rb2b-script');
      if (scriptElement) {
        scriptElement.remove();
      }
    };
  }, [pathname]);


return null;
}