-
Notifications
You must be signed in to change notification settings - Fork 164
[DX-1958] Add "Ask AI" to docs website #6317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
PR Reviewer Guide 🔍(Review updated until commit d2091f5)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨No code suggestions found for the PR. |
✅ PS. Pls add /docs/nightly to the end of url
To edit notification comments on pull requests, go to your Netlify site configuration. |
/help "can you review the PR again" |
/probe "Can you review the PR?" |
Code Review: Add "Ask AI" to docs website (Updated)OverviewThis PR adds an AI chat widget to the Tyk documentation website, allowing users to ask questions about Tyk products and receive AI-generated responses. The implementation has been significantly improved from the initial version. Positive Changes1. Security ImprovementsThe critical XSS vulnerability has been addressed by enabling sanitization in marked.js: marked.setOptions({
// ...
sanitize: true, // Enable sanitization to prevent XSS
// ...
}); 2. Enhanced UI/UX
3. Improved Error HandlingThe code now handles different error scenarios more gracefully: if (error.name === 'AbortError') {
rawContentContainer.textContent = 'Request was cancelled.';
} else {
rawContentContainer.textContent = 'Sorry, something went wrong with the streaming connection.';
} 4. Better Code Organization
Remaining Issues1. Hardcoded API EndpointThe API endpoint is still hardcoded: fetch('https://tyk-docs-ask-ai.dokku.tyk.technology/api/stream', {
method: 'POST',
headers: headers,
body: JSON.stringify({ messages: messages }),
signal: signal
}) Recommendation: Make the endpoint configurable via environment variables or a config object: const apiEndpoint = window.TYK_CONFIG?.aiChatEndpoint || '/api/ai/stream';
fetch(apiEndpoint, {
// ...
}) 2. External Dependencies Without SRIThe widget still loads external scripts without Subresource Integrity (SRI) checks: <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/styles/github.min.css">
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/highlight.min.js"></script> Recommendation: Add SRI hashes to ensure the integrity of external resources: <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"
integrity="sha384-[hash]" crossorigin="anonymous"></script> 3. Accessibility ImprovementsWhile the UI has improved, there are still some accessibility enhancements that could be made: Recommendation: Add ARIA attributes to improve screen reader support: <div id="chat-bubble" aria-label="Open chat assistant" role="button" tabindex="0" class="..."> SummaryThis PR has significantly improved from its initial implementation, particularly in addressing the critical XSS vulnerability. The UI/UX enhancements and better error handling make for a more robust user experience. The remaining issues are relatively minor and could be addressed in follow-up PRs. The hardcoded API endpoint is the most important remaining issue as it could cause deployment problems across different environments. Overall, with the security improvements in place, this PR is in good shape for merging, though addressing the hardcoded endpoint would be strongly recommended before deployment to production. Tip: Mention me again using |
Co-authored-by: yuri <8012032+yurisasuke@users.noreply.github.com>
/probe "We are using marked.js v15.0.11, but from the review and from marked.js it is found that the |
Security Issue: XSS Vulnerability in AI Chat WidgetProblem IdentifiedThe AI chat widget is using marked.js version 15.0.11 with the
Solution: Implement DOMPurify for HTML SanitizationSince marked.js no longer handles sanitization internally, we need to add a dedicated HTML sanitization library. The marked.js documentation recommends DOMPurify as the preferred solution. Step 1: Add DOMPurify to the HTML file<!-- In ai-chat-widget.html, add this before the chat.js script -->
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.0.6/dist/purify.min.js"></script> Step 2: Remove the deprecated sanitize option// In chat.js - Update the marked.js configuration
marked.setOptions({
renderer: new marked.Renderer(),
highlight: function (code, language) {
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(code, { language: validLanguage }).value;
},
pedantic: false,
gfm: true,
breaks: true,
// Remove this line as it's no longer supported:
// sanitize: true,
smartypants: false,
xhtml: false
}); Step 3: Update the renderMarkdown function to use DOMPurify// In chat.js - Update the renderMarkdown function
function renderMarkdown(accumulatedText, container) {
// Reset UI
chatStop.classList.add('hidden');
chatSubmit.classList.remove('hidden');
activeController = null;
try {
const markdownContainer = document.createElement('div');
markdownContainer.className = 'markdown-content';
// Convert markdown to HTML
const rawHtml = marked.parse(accumulatedText);
// Sanitize the HTML with DOMPurify before inserting into DOM
const sanitizedHtml = DOMPurify.sanitize(rawHtml);
markdownContainer.innerHTML = sanitizedHtml;
container.replaceWith(markdownContainer);
// Add assistant response to history
if (accumulatedText) {
messagesHistory.push({
role: "assistant",
content: accumulatedText
});
}
document.querySelectorAll('pre code').forEach((block) => {
hljs.highlightElement(block);
});
} catch (error) {
console.error('Error rendering final markdown:', error);
}
} Step 4: Also sanitize user input in onUserRequest functionSince user input is also directly inserted into the DOM, it should be sanitized as well: function onUserRequest(message) {
// Display user message
const messageElement = document.createElement('div');
messageElement.className = 'user-message';
// Sanitize user input before inserting into DOM
const sanitizedMessage = DOMPurify.sanitize(message);
messageElement.innerHTML = `
<div class="message-bubble user-bubble">
${sanitizedMessage}
</div>
`;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
// Rest of the function remains the same...
} Additional Recommendations
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.0.6/dist/purify.min.js"
integrity="sha384-..."
crossorigin="anonymous"></script>
// At the top of the file, define a configurable endpoint
const API_ENDPOINT = window.TYK_DOCS_AI_ENDPOINT || 'https://tyk-docs-ask-ai.dokku.tyk.technology/api/stream';
// Then use it in the fetch call
fetch(API_ENDPOINT, {
// ...
})
By implementing these changes, you'll properly secure the AI chat widget against XSS vulnerabilities while maintaining all the functionality. Tip: Mention me again using |
/release to release-5.8 |
Working on it! Note that it can take a few minutes. |
(cherry picked from commit 6c160f5)
@sharadregoti Created merge PRs |
Add "Ask AI" to docs website (#6317)
User description
Preview Link
Checklist
New Contributors
master
.PR Type
Enhancement, Documentation
Description
Introduces an interactive AI chat widget to the docs site.
Adds frontend logic for streaming AI responses with markdown support.
Implements custom styles for chat UI and markdown rendering.
Integrates widget into site layout via a new partial template.
Changes walkthrough 📝
ai-chat-widget.html
Introduce AI chat widget partial with UI and dependencies
tyk-docs/themes/tykio/layouts/partials/ai-chat-widget.html
chat.js
Add frontend logic for AI chat widget with streaming
tyk-docs/static/js/chat.js
chat.css
Add custom CSS for chat widget and markdown rendering
tyk-docs/static/css/chat.css
baseof.html
Integrate AI chat widget partial into base layout
tyk-docs/themes/tykio/layouts/_default/baseof.html