nlkitai / nlux

The π—£π—Όπ˜„π—²π—Ώπ—³π˜‚π—Ή Conversational AI JavaScript Library πŸ’¬ β€”Β UI for any LLM, supporting LangChain / HuggingFace / Vercel AI, and more 🧑 React, Next.js, and plain JavaScript ⭐️
https://docs.nlkit.com/nlux
Other
937 stars 48 forks source link

Error with Content-Security-Policy/Feature-Request #61

Closed wija1024 closed 1 month ago

wija1024 commented 1 month ago

Hi,

we use the Content-Security-Policy: require-trusted-types-for 'script'; and we do not have the possibility to define a sanitizer for HTML. Is there a possibility to integrate this feature in your project? Thanks in advance!

wija1024 commented 1 month ago

Would you be open to accepting a change that would make this configurable?

FloK8 commented 1 month ago

@salmenus did you come across this issue so far? I have the same problem with CSP.

salmenus commented 1 month ago

@wija1024 β€”Β I see that you're working on solving this issue. I'll be happy to assist with your PR and changes. Feel free to ping me on Discord for live chat on your suggested code changes.

salmenus commented 1 month ago

HTML Sanitiser Option Added

Please note that v2.x-beta has several config params that are different from v1, and the default theme has changed. If you're still using using v1, you'll need to upgrade the config, and explicitly set the theme to luna if you want to keep the old theme.

Β htmlSanitizer Usage

SanitizerExtension interface:

const myHtmlSanitizer: SanitizerExtension = (html: string): string => {
    // sanitize
    return newSanitizedHtml;
};

Usage in your React component:

<AiChat
    messageOptions={{
        htmlSanitizer: myHtmlSanitizer
    }}
/>

Related code changes can be found here.

salmenus commented 1 month ago

Example with TrustedHTML policy and DOMPurify

The example is running here. That's how I implement it in production. Please use v2.1.13-beta or a newer version.

Code snippet:

  import {SanitizerExtension} from '@nlux/react';
  import DOMPurify from "dompurify";

  const domPurifyHtmlSanitizer: SanitizerExtension = useMemo(
    () => (html: string) => {
      const trustedTypes = window.trustedTypes as unknown as {
        createPolicy: (
          name: string,
          policy: Record<string, unknown>
        ) => unknown;
      };

      if (typeof trustedTypes.createPolicy === "function") {
        const policy = trustedTypes.createPolicy("htmlSanitizer", {
          createHTML: (input: string) => DOMPurify.sanitize(input),
        });

        return policy.createHTML(html);
      }
      return DOMPurify.sanitize(html);
    },
    []
  );

Then pass it to <AiChat /> as part of the messageOptions:

<AiChat
    messageOptions={{
        htmlSanitizer: domPurifyHtmlSanitizer
    }}
/>
wija1024 commented 1 month ago

Thank you for adding this option and the detailed explanation on how to use it!