-
Notifications
You must be signed in to change notification settings - Fork 3
Enhance multi svm search updated #43
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
base: main
Are you sure you want to change the base?
Conversation
The commit implements a feature-rich search experience by replacing the basic HomeSearch component with a new EnhancedSearchBar. This adds advanced filtering capabilities with network selection, data type filtering, sorting options, and date/amount range filters.
Ensure at least one network and data type remain selected, add helpful messages, and set defaults when no data types are selected.
feat: implement search bar theme integration and command+k shortcut
fix: update Select component to use theme variables instead of hardco…
…sing error in xcom-search.ts
Reviewer's GuideThis PR refactors the search feature by integrating AI-powered analysis via OpenRouter, enhancing blockchain data retrieval with a comprehensive Moralis API client, overhauling the UI with a consolidated EnhancedSearchBar and multi-source tabs, and introducing interactive data visualization components—all while adding caching, batch processing, and relevance scoring for performance and augmenting documentation and tests. Sequence Diagram for AI-Powered SearchsequenceDiagram
actor User
participant ESP as EnhancedSearchBar
participant ARP as AIResponsePanel
participant OR_API as OpenRouter API
participant M_API as Moralis API
User->>ESP: Enters search query
ESP->>ARP: Displays and passes query
ARP->>M_API: Request comprehensive blockchain data (query)
M_API-->>ARP: Return blockchain data
ARP->>OR_API: Request AI analysis (query, blockchain data)
activate OR_API
OR_API-->>ARP: Stream AI response
deactivate OR_API
ARP->>User: Display AI-enhanced results and sources
Sequence Diagram for Multi-Platform SearchsequenceDiagram
actor User
participant ESP as EnhancedSearchBar
participant USL as UnifiedSearchLib
participant SVM_API as SVM API
participant TG_API as Telegram API
participant DDG_API as DuckDuckGo API
participant X_API as X.com API
User->>ESP: Enters search query
User->>ESP: Selects search sources (e.g., SVM, Telegram)
ESP->>USL: unifiedSearch(query, options)
activate USL
USL->>SVM_API: Search SVM (query)
SVM_API-->>USL: SVM results
USL->>TG_API: Search Telegram (query)
TG_API-->>USL: Telegram results
USL->>DDG_API: Search DuckDuckGo (query)
DDG_API-->>USL: DuckDuckGo results
USL->>X_API: Search X.com (query)
X_API-->>USL: X.com results
USL-->>ESP: Combined and formatted results
deactivate USL
ESP->>User: Display multi-platform search results
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
✅ Deploy Preview for opensvm ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary:
This PR enhances the multi-SVM search experience with AI-powered features, integration of OpenRouter API for blockchain analysis, improved Moralis API support, and a more interactive interface. Key additions include the EnhancedSearchBar
component, AI-enhanced results panel with streaming responses, multi-platform search capabilities across Solana VM/Telegram/DuckDuckGo/X.com, and interactive data visualizations for blockchain data.
Review Summary:
My review identified several critical security issues related to hardcoded API keys and potential XSS vulnerabilities that should be addressed before merging. I also found a few bugs including race conditions in error handling and improper routing patterns. The code demonstrates a sophisticated approach to unified search and AI integration, but needs security improvements to meet production standards. Please provide feedback on this review which I'll consider for future reviews.
Follow-up suggestions:
@devloai implement proper API key security using environment variables only
@devloai add proper error handling for missing API keys
import axios from 'axios'; | ||
|
||
// OpenRouter API configuration | ||
const OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY || 'sk-or-v1-free-tier-demo-key'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OpenRouter API key is exposed with a default fallback value. Even if it's a free tier key, API keys should never be included in the source code. Instead, handle missing API keys with a proper error and implement a better fallback mechanism.
import axios from 'axios'; | ||
|
||
// Moralis API configuration | ||
const MORALIS_API_KEY = process.env.MORALIS_API_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJub25jZSI6IjRjOTdiNjY5LWU0NTAtNDc0ZC04NDk5LWM3MzQ3MTY2MzZjZSIsIm9yZ0lkIjoiNDM3NTQzIiwidXNlcklkIjoiNDUwMTMwIiwidHlwZUlkIjoiZjY3MzczODctNjQ1MC00YzIyLTg1YjAtOWI1ZjE3NWE3ZWQ3IiwidHlwZSI6IlBST0pFQ1QiLCJpYXQiOjE3NDI2MzYxMDcsImV4cCI6NDg5ODM5NjEwN30.bLDNejPrPEg9tFbmUITy9cpuMBuvU5pzbloq0b-7r4A'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A hardcoded Moralis API key is included in the source code. This is a serious security risk as API keys should never be committed to repositories. Instead, rely solely on environment variables and implement proper error handling when keys are missing.
// Create prompt with blockchain data | ||
const prompt = openrouter.createBlockchainSearchPrompt(searchQuery, data); | ||
|
||
// Switch to streaming mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential race condition in error handling. If the blockchainDataPromise
fails, you're still trying to use data
in the streaming response which could be undefined. Restructure this to ensure the AI response generation only proceeds if blockchain data is successfully retrieved, or implement proper null checking when passing data to openrouter.createBlockchainSearchPrompt
.
${date ? `<span class="text-xs text-muted-foreground">${formattedDate}</span>` : ''} | ||
</div> | ||
<p class="mt-1 text-sm">${result.content}</p> | ||
${result.url ? ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The renderUnifiedSearchResult
function outputs raw HTML without proper sanitization. This could lead to XSS vulnerabilities if result content contains malicious scripts. Implement proper HTML sanitization for user-generated or API-provided content before rendering.
Sorry, something went wrong.
All reactions
components/search/index.tsx
Outdated
window.location.href = `/token/${trimmedQuery}`; | ||
break; | ||
case 'program': | ||
window.location.href = `/program/${trimmedQuery}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Direct window location manipulation in the search handling logic can cause issues with Next.js routing and history management. Replace window.location.href
with the Next.js router for client-side navigation:
window.location.href = `/program/${trimmedQuery}`; | |
router.push(`/program/${trimmedQuery}`); |
Sorry, something went wrong.
All reactions
// Handle rate limiting | ||
if (error.response && error.response.status === 429) { | ||
console.error('Rate limit exceeded for Moralis API. Retrying after delay...'); | ||
await new Promise(resolve => setTimeout(resolve, 2000)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rate limiting retry mechanism uses a fixed 2 second delay. Consider implementing an exponential backoff strategy for retries to better handle extended rate limiting periods and reduce unnecessary API calls during high traffic.
Sorry, something went wrong.
All reactions
)} | ||
|
||
<button | ||
> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better accessibility, the close button should include an aria-label
attribute to help screen reader users identify its purpose.
Sorry, something went wrong.
All reactions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @0xrinegade - I've reviewed your changes and found some issues that need to be addressed.
Blocking issues:
- Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data. (link)
- Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data. (link)
- JWT token detected (link)
- Returning raw HTML string risks XSS (link)
General comments:
- This PR touches many areas (AI integration, API enhancements, UI/UX, visualizations); consider breaking it up into smaller, focused PRs so each feature can be reviewed and tested independently.
- There’s a lot of repeated logic (AI streaming, prompt generation, chart setup) scattered inline in components—extracting these into reusable hooks or utility modules will reduce duplication and improve maintainability.
- Most visualization components share similar setup (ResponsiveContainer wrappers, Card headers, skeletons); consider abstracting common chart boilerplate into a shared component or HOC to keep your code DRY.
Here's what I looked at during the review
- 🟡 General issues: 17 issues found
- 🔴 Security: 3 blocking issues
- 🟡 Testing: 1 issue found
- 🟡 Complexity: 4 issues found
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
app/search/page.tsx
Outdated
setIsAiThinking(true); | ||
|
||
// Simulate API call delay | ||
const thinkingTimer = setTimeout(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Timers not fully cleaned up on unmount
Capture both thinkingTimer
and streamInterval
in the outer scope and clear them in the useEffect
cleanup to prevent memory leaks.
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction 1E79
app/search/page.tsx
Outdated
} | ||
}, 15); // Stream characters at a natural typing speed | ||
|
||
return () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Misplaced cleanup return
The return
should be directly inside the useEffect
to ensure React calls the cleanup function. Move the cleanup logic out of the setTimeout
callback.
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
)} | ||
</div> | ||
)} | ||
<button |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): AI panel close has no reopen control
After closing the AI panel, users cannot reopen it without refreshing the page. Please add a way to toggle the panel back on.
Suggested implementation:
<button
onClick={() => setShowAiPanel(false)}
className="text-muted-foreground hover:text-foreground transition-colors duration-200"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clipRule="evenodd" />
</svg>
</button>
</div>
</CardHeader>
<CardContent className="p-4">
{isAiThinking ? (
<div className="h-24 flex items-center justify-center">
=======
{/* Add this toggle button outside the AI panel, e.g. at the top of the page/component */}
{!showAiPanel && (
<button
onClick={() => setShowAiPanel(true)}
className="fixed bottom-4 right-4 z-50 bg-background border border-border rounded-full shadow-lg px-4 py-2 text-sm text-muted-foreground hover:text-foreground transition-colors duration-200"
aria-label="Open AI Panel"
>
<svg xmlns="http://www.w3.org/2000/svg" className="inline h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
<path d="M10 2a8 8 0 100 16 8 8 0 000-16zm1 11H9v-1h2v1zm0-3H9V7h2v3z" />
</svg>
Open AI Panel
</button>
)}
- Make sure that
showAiPanel
andsetShowAiPanel
are defined in the parent component's state (likely viauseState
). If not, add:at the top of your component.const [showAiPanel, setShowAiPanel] = useState(true);
- Place the new toggle button outside the conditional rendering of the AI panel, so it is always available when the panel is closed.
- Adjust the button's position and style as needed to fit your UI/UX.
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
return response.data; | ||
} catch (error: any) { | ||
// Handle rate limiting | ||
if (error.response && error.response.status === 429) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): Infinite retry loop on rate limit
Currently, repeated 429 responses will cause endless retries. Please implement a maximum retry limit or exponential backoff to prevent this.
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
* @param result - Search result to render | ||
* @returns HTML string for the result card | ||
*/ | ||
export function renderUnifiedSearchResult(result: UnifiedSearchResult): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 issue (security): Returning raw HTML string risks XSS
Consider returning React elements or sanitized content to prevent XSS vulnerabilities.
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
import axios from 'axios'; | ||
|
||
// Moralis API configuration | ||
const MORALIS_API_KEY = process.env.MORALIS_API_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJub25jZSI6IjRjOTdiNjY5LWU0NTAtNDc0ZC04NDk5LWM3MzQ3MTY2MzZjZSIsIm9yZ0lkIjoiNDM3NTQzIiwidXNlcklkIjoiNDUwMTMwIiwidHlwZUlkIjoiZjY3MzczODctNjQ1MC00YzIyLTg1YjAtOWI1ZjE3NWE3ZWQ3IiwidHlwZSI6IlBST0pFQ1QiLCJpYXQiOjE3NDI2MzYxMDcsImV4cCI6NDg5ODM5NjEwN30.bLDNejPrPEg9tFbmUITy9cpuMBuvU5pzbloq0b-7r4A'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
security (detected-jwt-token): JWT token detected
Source: opengrep
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
|
||
// AI Response Generation | ||
useEffect(() => { | ||
if (!query) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces
)
if (!query) return; | |
if (!query) { |
Explanation
It is recommended to always use braces and create explicit statement blocks.Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
if (rarity < 50) rarityDistribution[0].value++; | ||
else if (rarity < 70) rarityDistribution[1].value++; | ||
else if (rarity < 85) rarityDistribution[2].value++; | ||
else if (rarity < 95) rarityDistribution[3].value++; | ||
else rarityDistribution[4].value++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces
)
if (rarity < 50) rarityDistribution[0].value++; | |
else if (rarity < 70) rarityDistribution[1].value++; | |
else if (rarity < 85) rarityDistribution[2].value++; | |
else if (rarity < 95) rarityDistribution[3].value++; | |
else rarityDistribution[4].value++; | |
if (rarity < 50) { | |
rarityDistribution[0].value++; | |
} else if (rarity < 70) rarityDistribution[1].value++; | |
else if (rarity < 85) rarityDistribution[2].value++; | |
else if (rarity < 95) rarityDistribution[3].value++; | |
else rarityDistribution[4].value++; | |
Explanation
It is recommended to always use braces and create explicit statement blocks.Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
else if (rarity < 70) rarityDistribution[1].value++; | ||
else if (rarity < 85) rarityDistribution[2].value++; | ||
else if (rarity < 95) rarityDistribution[3].value++; | ||
else rarityDistribution[4].value++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces
)
else if (rarity < 70) rarityDistribution[1].value++; | |
else if (rarity < 85) rarityDistribution[2].value++; | |
else if (rarity < 95) rarityDistribution[3].value++; | |
else rarityDistribution[4].value++; | |
else if (rarity < 70) { | |
rarityDistribution[1].value++; | |
} else if (rarity < 85) rarityDistribution[2].value++; | |
else if (rarity < 95) rarityDistribution[3].value++; | |
else rarityDistribution[4].value++; | |
Explanation
It is recommended to always use braces and create explicit statement blocks.Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
else if (rarity < 85) rarityDistribution[2].value++; | ||
else if (rarity < 95) rarityDistribution[3].value++; | ||
else rarityDistribution[4].value++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Use block braces for ifs, whiles, etc. (use-braces
)
else if (rarity < 85) rarityDistribution[2].value++; | |
else if (rarity < 95) rarityDistribution[3].value++; | |
else rarityDistribution[4].value++; | |
else if (rarity < 85) { | |
rarityDistribution[2].value++; | |
} else if (rarity < 95) rarityDistribution[3].value++; | |
else rarityDistribution[4].value++; | |
Explanation
It is recommended to always use braces and create explicit statement blocks.Using the allowed syntax to just write a single statement can lead to very confusing
situations, especially where subsequently a developer might add another statement
while forgetting to add the braces (meaning that this wouldn't be included in the condition).
Sorry, something went wrong.
All reactions
-
👍 1 reaction -
👎 1 reaction
url: `https://t.me/${channel.id}` | ||
}, | ||
sender: { | ||
username: `user_${Math.random().toString(36).substring(2, 10)}`, |
Check failure
Code scanning / CodeQL
Insecure randomness High
Math.random()
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 17 days ago
To fix the issue, replace the use of Math.random()
with a cryptographically secure random number generator. In Node.js, the crypto
module provides a secure method for generating random values. Specifically, crypto.randomBytes
can be used to generate random bytes, which can then be converted to a string for use in the username.
The fix involves:
- Importing the
crypto
module. - Replacing the
Math.random()
call with a secure random string generated usingcrypto.randomBytes
. - Ensuring the generated string is of the same format and length as the original.
-
Copy modified line R1 -
Copy modified line R82
@@ -1 +1,2 @@ | ||
import * as crypto from 'crypto'; | ||
/** | ||
@@ -80,3 +81,3 @@ | ||
sender: { | ||
username: `user_${Math.random().toString(36).substring(2, 10)}`, | ||
username: `user_${crypto.randomBytes(6).toString('base64url').substring(0, 8)}`, | ||
displayName: generateRandomName() |
…ace protocol support
…ions to resolve workspace protocol error
…hes with ASCII ones
const results = []; | ||
|
||
for (let i = 0; i < Math.min(limit, 20); i++) { | ||
const account = accounts[Math.floor(Math.random() * accounts.length)]; |
Check failure
Code scanning / CodeQL
Insecure randomness High
Math.random()
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 16 days ago
To fix the issue, we will replace all instances of Math.random()
with a cryptographically secure random number generator. In Node.js, the crypto
module provides a secure method for generating random values. Specifically, we will use crypto.randomInt()
to generate random integers securely. This ensures that the randomness is not predictable and meets cryptographic standards.
The changes will involve:
- Importing the
crypto
module at the top of the file. - Replacing
Math.random()
withcrypto.randomInt()
in all relevant locations, ensuring the functionality remains the same.
-
Copy modified line R1 -
Copy modified lines R68-R69 -
Copy modified line R73 -
Copy modified line R76 -
Copy modified line R90
@@ -1 +1,2 @@ | ||
import * as crypto from 'crypto'; | ||
/** | ||
@@ -66,4 +67,4 @@ | ||
for (let i = 0; i < Math.min(limit, 20); i++) { | ||
const account = accounts[Math.floor(Math.random() * accounts.length)]; | ||
const tweetTemplate = tweetTemplates[Math.floor(Math.random() * tweetTemplates.length)]; | ||
const account = accounts[crypto.randomInt(0, accounts.length)]; | ||
const tweetTemplate = tweetTemplates[crypto.randomInt(0, tweetTemplates.length)]; | ||
const tweet = tweetTemplate.replace('{query}', query); | ||
@@ -71,6 +72,6 @@ | ||
// Random date within last 7 days | ||
const timestamp = new Date(Date.now() - Math.floor(Math.random() * 7 * 24 * 60 * 60 * 1000)); | ||
const timestamp = new Date(Date.now() - crypto.randomInt(0, 7 * 24 * 60 * 60 * 1000)); | ||
|
||
results.push({ | ||
id: `tweet_${Math.random().toString(36).substring(2, 15)}`, | ||
id: `tweet_${crypto.randomBytes(8).toString('hex')}`, | ||
type: 'x_com', | ||
@@ -88,3 +89,3 @@ | ||
replies: Math.floor(Math.random() * 200), | ||
url: `https://x.com/${account.handle}/status/${Math.random().toString(36).substring(2, 15)}` | ||
url: `https://x.com/${account.handle}/status/${crypto.randomBytes(8).toString('hex')}` | ||
}); |
const sanitized = text | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') | ||
.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '') |
Check failure
Code scanning / CodeQL
Incomplete multi-character sanitization High
<iframe
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 16 days ago
To fix the issue, we will modify the sanitizeAiResponseText
function to repeatedly apply the regular expression replacements until no further matches are found. This ensures that all instances of the targeted patterns are removed, even if they are nested or malformed. This approach is a straightforward way to address the incomplete sanitization issue without introducing significant complexity.
-
Copy modified lines R46-R54
@@ -45,6 +45,11 @@ | ||
// Remove any potentially harmful HTML | ||
const sanitized = text | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') | ||
.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '') | ||
.replace(/<img[^>]*>/gi, '[IMAGE]'); | ||
let sanitized = text; | ||
let previous; | ||
do { | ||
previous = sanitized; | ||
sanitized = sanitized | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') | ||
.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '') | ||
.replace(/<img[^>]*>/gi, '[IMAGE]'); | ||
} while (sanitized !== previous); | ||
|
const sanitized = text | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') |
Check failure
Code scanning / CodeQL
Incomplete multi-character sanitization High
<script
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 16 days ago
To fix the issue, we will modify the sanitizeAiResponseText
function to repeatedly apply the regular expression replacements until no more matches are found. This ensures that all instances of the targeted patterns are removed, even if they are nested or malformed. Additionally, we will recommend using a well-tested sanitization library like sanitize-html
for more robust and comprehensive sanitization.
-
Copy modified lines R46-R54
@@ -45,6 +45,11 @@ | ||
// Remove any potentially harmful HTML | ||
const sanitized = text | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') | ||
.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '') | ||
.replace(/<img[^>]*>/gi, '[IMAGE]'); | ||
let sanitized = text; | ||
let previous; | ||
do { | ||
previous = sanitized; | ||
sanitized = sanitized | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') | ||
.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '') | ||
.replace(/<img[^>]*>/gi, '[IMAGE]'); | ||
} while (sanitized !== previous); | ||
|
export function sanitizeAiResponseText(text: string): string { | ||
// Remove any potentially harmful HTML | ||
const sanitized = text | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') |
Check failure
Code scanning / CodeQL
Bad HTML filtering regexp High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 16 days ago
The best way to fix this issue is to replace the custom regular expression-based sanitization with a well-tested HTML sanitization library, such as DOMPurify
. These libraries are specifically designed to handle edge cases and ensure that potentially harmful HTML is removed safely. This approach is more robust and secure than attempting to fix the regex manually.
To implement the fix:
- Install the
dompurify
library. - Replace the custom regex-based sanitization logic in the
sanitizeAiResponseText
function with a call toDOMPurify.sanitize
. - Ensure that the library is imported and properly configured.
-
Copy modified lines R44-R45 -
Copy modified lines R47-R48
@@ -43,9 +43,7 @@ | ||
// Utility function to sanitize AI response text | ||
import DOMPurify from 'dompurify'; | ||
|
||
export function sanitizeAiResponseText(text: string): string { | ||
// Remove any potentially harmful HTML | ||
const sanitized = text | ||
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') | ||
.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '') | ||
.replace(/<img[^>]*>/gi, '[IMAGE]'); | ||
|
||
// Use DOMPurify to sanitize the input text | ||
const sanitized = DOMPurify.sanitize(text, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] }); | ||
return sanitized; |
-
Copy modified lines R86-R87
@@ -85,3 +85,4 @@ | ||
"zod": "^3.24.1", | ||
"zod-to-json-schema": "^3.23.0" | ||
"zod-to-json-schema": "^3.23.0", | ||
"dompurify": "^3.2.6" | ||
}, |
Package | Version | Security advisories |
dompurify (npm) | 3.2.6 | None |
devloai[bot]
sourcery-ai[bot]
Successfully merging this pull request may close these issues.
This pull request introduces significant enhancements to the multi-SVM search user experience, including AI-powered features, improved blockchain data integration, and a more interactive and visually appealing interface. Key updates include the integration of the OpenRouter API for AI-driven blockchain analysis, enhanced Moralis API support, new data visualization components, and performance optimizations. Additionally, the search interface has been upgraded with smooth animations and unified multi-platform search capabilities.
AI Enhancements and Blockchain Data Integration:
Search Interface Improvements:
EnhancedSearchBar
component across multiple files (HomeSearch.tsx
,search/page.tsx
). [1] [2]Data Visualizations and User Experience:
Performance Optimizations:
Documentation and Testing:
docs/enhanced-search.md
covering features, components, and API integration.Summary by Sourcery
Provide an AI-powered, multi-platform search experience with enriched blockchain data visualizations, smooth animated UI components and performance optimizations.
New Features:
Enhancements:
Documentation:
Tests: