Skip to content
Open
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
1,026 changes: 1,026 additions & 0 deletions backend/api_server.py

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions backend/requirements-api.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Backend API Server Requirements
fastapi==0.104.1
uvicorn[standard]==0.24.0
python-multipart==0.0.6
pydantic==2.5.0
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
aiofiles==23.2.0
Comment on lines +1 to +8

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 | πŸ”΄ Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch latest versions from PyPI for comparison
python - <<'PY'
import json, urllib.request
pkgs = ["fastapi","uvicorn","python-multipart","pydantic","python-jose","passlib","aiofiles"]
print("Package comparison (pinned vs latest):\n")
pinned = {
    "fastapi": "0.104.1",
    "uvicorn": "0.24.0",
    "python-multipart": "0.0.6",
    "pydantic": "2.5.0",
    "python-jose": "3.3.0",
    "passlib": "1.7.4",
    "aiofiles": "23.2.0"
}
for p in pkgs:
    try:
        data = json.load(urllib.request.urlopen(f"https://pypi.org/pypi/{p}/json"))
        latest = data['info']['version']
        pinned_ver = pinned.get(p, "unknown")
        print(f"{p:20} | pinned: {pinned_ver:10} | latest: {latest}")
    except Exception as e:
        print(f"{p}: Error fetching - {e}")
PY

Repository: thrishank007/NeuraX

Length of output: 1195


🌐 Web query:

fastapi latest version 2024 2025 security updates

πŸ’‘ Result:

Latest FastAPI version (as of Jan 30, 2026)

  • FastAPI 0.128.0 (released Dec 27, 2025) is the current latest release on PyPI. (pypi.org)

Notable 2024–2025 security-relevant updates (FastAPI + common transitive issues)

  • CVE-2024-24762 (ReDoS via python-multipart when parsing form-data Content-Type)
    • Affected: FastAPI <= 0.109.0
    • Fixed: 0.109.1 (by requiring python-multipart >= 0.0.7) (data.safetycli.com)
  • Starlette DoS/memory-exhaustion risk in older Starlette versions (transitive via FastAPI)
    • Reports note Starlette versions <= 0.49 as susceptible, and indicate this is addressed by upgrading FastAPI to at least 0.115.3 (released Oct 22, 2024). (recordedfuture.com)

Practical guidance

  • If you’re on FastAPI < 0.109.1, upgrade (covers the python-multipart ReDoS fix). (data.safetycli.com)
  • If you want to ensure you’re past the β€œold Starlette” DoS concern referenced above, use FastAPI >= 0.115.3 and ensure your installed Starlette is current. (recordedfuture.com)
  • To get everything current (framework + fixes + bugfixes), upgrade to 0.128.0. (pypi.org)

Citations:


🌐 Web query:

uvicorn latest version 2024 2025 security advisories

πŸ’‘ Result:

Latest Uvicorn (Python / PyPI)

  • Latest release: uvicorn 0.40.0 (uploaded Dec 21, 2025). (pypi.org)
  • GitHub β€œLatest” tag also shows 0.40.0. (github.com)

Security advisories relevant to 2024–2025

Uvicorn (Python) CVEs/advisories

There don’t appear to be newly issued 2024–2025 CVEs for the PyPI uvicorn package itself in the major public advisory feeds surfaced here; the commonly referenced Uvicorn issues are older, but their advisory records were updated in Nov 2024:

β€œUvicorn” mentioned in 2024–2025 CVEs, but not a Uvicorn bug

  • CVE-2024-10906 is about db-gpt’s CORSMiddleware configuration in an app that uses Uvicorn (a deployment/app misconfiguration), not a vulnerability in Uvicorn itself. (nvd.nist.gov)

Name-collision warning: malicious npm package named uvicorn (not Python Uvicorn)

  • MAL-2025-4901 / GHSA-2pw2-crvh-r9c5: malicious code in uvicorn on npm (JavaScript ecosystem). This is separate from Python’s uvicorn on PyPI. (osv.dev)

Practical takeaway

  • For Python projects, upgrade to uvicorn 0.40.0 (or newer, if released after Dec 21, 2025). (pypi.org)
  • If you use npm in your toolchain, ensure you didn’t accidentally pull the npm uvicorn package (malware advisory above). (osv.dev)

Citations:


🌐 Web query:

pydantic 2.5.0 latest version 2024 2025 security

πŸ’‘ Result:

  • Pydantic 2.5.0 is not the latest. It was released 2023-11-13. [3]
  • The latest Pydantic (v2) release on PyPI (as of 2026-01-30) is 2.12.5, released 2025-11-26. [1]

Security (2024–2025)

  • The main widely published Pydantic v2 security issue in that window is CVE-2024-3772 (regex DoS via crafted email string). It affects pydantic >=2.0.0,<2.4.0 (and <1.10.13 for v1), and is patched in 2.4.0. [2][4]
    • Therefore, Pydantic 2.5.0 is not affected by CVE-2024-3772 (it’s already > 2.4.0). [2]

Practical recommendation

  • If you’re on 2.5.0, upgrade to the latest patch/minor (currently 2.12.5) to pick up ongoing bugfixes and reduce exposure to newly discovered issues. [1]

Sources:
[1] PyPI pydantic (latest version/date)
[2] GitHub Advisory Database entry for CVE-2024-3772 (affected/patched versions)
[3] Pydantic changelog entry for v2.5.0 (release date)
[4] Ubuntu CVE entry for CVE-2024-3772 (description/affected versions)


🌐 Web query:

python-jose passlib aiofiles latest versions 2024 2025

πŸ’‘ Result:

Latest as of Jan 30, 2026 (from PyPI):

Package Latest version Release date Notes
python-jose 3.5.0 May 28, 2025 Current latest python-jose release. [1]
passlib 1.7.4 Oct 8, 2020 No 2024/2025 releases for passlib itself. [2]
(maintained fork) libpass 1.9.3 Oct 9, 2025 Active fork of Passlib with 2024–2025 releases. [3]
aiofiles 25.1.0 Oct 9, 2025 Latest; also had 24.1.0 on Jun 24, 2024. [4]

2024–2025 highlights:

  • python-jose: latest in that window is 3.5.0 (May 28, 2025). [1]
  • passlib: no releases in 2024/2025 (latest remains 1.7.4 from 2020). [2]
  • aiofiles: 24.1.0 (Jun 24, 2024) and 25.1.0 (Oct 9, 2025). [4]
  • If you meant β€œPasslib in 2024/2025”, that activity is under the fork libpass (e.g., 1.8.x in 2024, 1.9.x in 2025). [3]

Sources: [1] python-jose on PyPI, [2] passlib on PyPI, [3] libpass on PyPI, [4] aiofiles on PyPI.


Address CVE-2024-24762: upgrade FastAPI and python-multipart to patch ReDoS vulnerability in form-data parsing.

The current pins (fastapi==0.104.1 with python-multipart==0.0.6) are vulnerable to CVE-2024-24762, a ReDoS attack exploitable via crafted Content-Type headers in multipart form submissions. Minimum safe versions are fastapi>=0.109.1 and python-multipart>=0.0.7. Consider upgrading to current releases:

  • fastapi to 0.128.0 (Dec 2025)
  • uvicorn to 0.40.0 (Dec 2025)
  • pydantic to 2.12.5 (latest v2 stable, Nov 2025)
  • python-jose to 3.5.0 (May 2025)
  • aiofiles to 25.1.0 (Oct 2025)
  • passlib remains at 1.7.4 (project unmaintained since 2020; consider libpass fork if active maintenance is needed)
πŸ€– Prompt for AI Agents
In `@backend/requirements-api.txt` around lines 1 - 8, The requirements file pins
vulnerable versions of FastAPI and python-multipart (fastapi==0.104.1,
python-multipart==0.0.6) which are affected by CVE-2024-24762; update these
entries to at least fastapi>=0.109.1 and python-multipart>=0.0.7 to patch the
ReDoS in multipart form parsing, and consider updating other dependencies listed
(uvicorn, pydantic, python-jose, aiofiles) to the suggested newer versions
(e.g., uvicorn 0.40.0, pydantic 2.12.5, python-jose 3.5.0, aiofiles 25.1.0)
while keeping passlib as-is or replacing with a maintained fork if desired.

28 changes: 28 additions & 0 deletions neurax-frontend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Environment variables for NeuraX Frontend
# Copy this file to .env.local and configure as needed

# API Configuration
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_WS_URL=ws://localhost:8000
NEXT_PUBLIC_LM_STUDIO_URL=http://localhost:1234

# File Upload Settings
NEXT_PUBLIC_MAX_FILE_SIZE=104857600
NEXT_PUBLIC_ALLOWED_FILE_TYPES=.pdf,.docx,.doc,.txt,.jpg,.png,.mp3,.wav,.m4a,.flac,.ogg,.bmp,.tiff,.webp

# Feature Flags
NEXT_PUBLIC_ENABLE_ANALYTICS=true
NEXT_PUBLIC_ENABLE_DARK_MODE=true
NEXT_PUBLIC_ENABLE_VOICE_INPUT=true

# Query Settings
NEXT_PUBLIC_DEFAULT_SIMILARITY_THRESHOLD=0.5
NEXT_PUBLIC_MAX_QUERY_HISTORY=50

# Development Settings
NEXT_PUBLIC_DEBUG_MODE=false
NEXT_PUBLIC_LOG_LEVEL=info

# Optional: Custom model configurations
# NEXT_PUBLIC_CUSTOM_MODELS_PATH=/path/to/models
# NEXT_PUBLIC_ENABLE_EXPERIMENTAL_FEATURES=false
11 changes: 11 additions & 0 deletions neurax-frontend/.env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NeuraX Frontend Environment Variables
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_WS_URL=ws://localhost:8000
NEXT_PUBLIC_LM_STUDIO_URL=http://localhost:1234
NEXT_PUBLIC_MAX_FILE_SIZE=104857600
NEXT_PUBLIC_ALLOWED_FILE_TYPES=.pdf,.docx,.doc,.txt,.jpg,.png,.mp3,.wav,.m4a,.flac,.ogg,.bmp,.tiff,.webp
NEXT_PUBLIC_ENABLE_ANALYTICS=true
NEXT_PUBLIC_ENABLE_DARK_MODE=true
NEXT_PUBLIC_DEFAULT_SIMILARITY_THRESHOLD=0.5
NEXT_PUBLIC_MAX_QUERY_HISTORY=50
NEXT_PUBLIC_ENABLE_VOICE_INPUT=true
62 changes: 62 additions & 0 deletions neurax-frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Use the official Node.js 18 image
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json package-lock.json* ./
RUN npm ci --only=production && npm cache clean --force

# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1

RUN npm run build

# If using npm comment out above and use below instead
# RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000
# set hostname to localhost
ENV HOSTNAME "0.0.0.0"

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "server.js"]
50 changes: 50 additions & 0 deletions neurax-frontend/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
import { Toaster } from 'react-hot-toast'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
title: 'NeuraX - Multimodal RAG System',
description: 'Secure, offline multimodal retrieval-augmented generation system with document intelligence and analytics.',
keywords: 'RAG, multimodal, document intelligence, AI, security, offline',
authors: [{ name: 'NeuraX Team' }],
viewport: 'width=device-width, initial-scale=1',
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" suppressHydrationWarning>
<body className={inter.className}>
<div className="relative flex min-h-screen flex-col">
{children}
</div>
<Toaster
position="top-right"
toastOptions={{
duration: 4000,
style: {
background: 'hsl(var(--background))',
color: 'hsl(var(--foreground))',
border: '1px solid hsl(var(--border))',
},
success: {
className: 'toast-success',
},
error: {
className: 'toast-error',
},
loading: {
className: 'toast-info',
},
}}
/>
</body>
</html>
)
}
162 changes: 162 additions & 0 deletions neurax-frontend/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
'use client'

import { useState, useCallback } from 'react'
import { Header } from '@/components/common/Header'
import { FileUploader } from '@/components/upload/FileUploader'
import { QueryInterface } from '@/components/query/QueryInterface'
import { ResultsDisplay } from '@/components/results/ResultsDisplay'
import { AnalyticsDashboard } from '@/components/analytics/AnalyticsDashboard'
import { QueryHistory } from '@/components/query/QueryHistory'
import { Settings } from '@/components/common/Settings'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { FileText, Search, BarChart3, History, Settings as SettingsIcon, Upload } from 'lucide-react'
import type { Query, SearchResult, FileUpload } from '@/types'

export default function HomePage() {
const [activeTab, setActiveTab] = useState<'query' | 'upload' | 'analytics' | 'history' | 'settings'>('query')
const [currentQuery, setCurrentQuery] = useState<Query | null>(null)
const [searchResults, setSearchResults] = useState<SearchResult[]>([])
const [uploadedFiles, setUploadedFiles] = useState<FileUpload[]>([])

const handleSearch = useCallback((query: Query) => {
setCurrentQuery(query)
// Search results will be set by the QueryInterface component
}, [])

const handleSearchResults = useCallback((results: SearchResult[]) => {
setSearchResults(results)
}, [])

const handleFileUpload = useCallback((files: FileUpload[]) => {
setUploadedFiles(prev => [...prev, ...files])
}, [])

const renderActiveTab = () => {
switch (activeTab) {
case 'upload':
return (
<FileUploader
onFileUpload={handleFileUpload}
uploadedFiles={uploadedFiles}
/>
)
case 'analytics':
return <AnalyticsDashboard />
case 'history':
return <QueryHistory />
case 'settings':
return <Settings />
case 'query':
default:
return (
<div className="space-y-6">
<QueryInterface
onSearch={handleSearch}
onResults={handleSearchResults}
uploadedFiles={uploadedFiles}
/>
{searchResults.length > 0 && (
<ResultsDisplay
query={currentQuery}
results={searchResults}
/>
)}
</div>
)
}
}

return (
<div className="min-h-screen bg-background">
<Header
onSearch={() => setActiveTab('query')}
onUpload={() => setActiveTab('upload')}
onAnalytics={() => setActiveTab('analytics')}
onHistory={() => setActiveTab('history')}
onSettings={() => setActiveTab('settings')}
/>

<main className="container mx-auto px-4 py-6">
{/* Tab Navigation */}
<div className="mb-6">
<div className="flex space-x-1 rounded-lg bg-muted p-1">
<Button
variant={activeTab === 'query' ? 'default' : 'ghost'}
size="sm"
onClick={() => setActiveTab('query')}
className="gap-2"
>
<Search className="h-4 w-4" />
Query & Search
</Button>
<Button
variant={activeTab === 'upload' ? 'default' : 'ghost'}
size="sm"
onClick={() => setActiveTab('upload')}
className="gap-2"
>
<Upload className="h-4 w-4" />
File Upload
</Button>
<Button
variant={activeTab === 'analytics' ? 'default' : 'ghost'}
size="sm"
onClick={() => setActiveTab('analytics')}
className="gap-2"
>
<BarChart3 className="h-4 w-4" />
Analytics
</Button>
<Button
variant={activeTab === 'history' ? 'default' : 'ghost'}
size="sm"
onClick={() => setActiveTab('history')}
className="gap-2"
>
<History className="h-4 w-4" />
History
</Button>
<Button
variant={activeTab === 'settings' ? 'default' : 'ghost'}
size="sm"
onClick={() => setActiveTab('settings')}
className="gap-2"
>
<SettingsIcon className="h-4 w-4" />
Settings
</Button>
</div>
</div>

{/* Tab Content */}
<div className="animate-fade-in">
{renderActiveTab()}
</div>

{/* Quick Stats Footer */}
{activeTab === 'query' && (
<Card className="mt-8">
<CardContent className="pt-6">
<div className="flex items-center justify-between text-sm text-muted-foreground">
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-1">
<div className="h-2 w-2 bg-green-500 rounded-full" />
<span>{uploadedFiles.length} files uploaded</span>
</div>
<div className="flex items-center space-x-1">
<div className="h-2 w-2 bg-blue-500 rounded-full" />
<span>{searchResults.length} results found</span>
</div>
</div>
<div>
System Status: Online
</div>
</div>
</CardContent>
</Card>
)}
</main>
</div>
)
}
Loading