feat(add templates):

This commit is contained in:
Alexander Myasoedov
2024-11-30 09:38:48 +02:00
parent f57f3e9f43
commit 789d0100f1
6 changed files with 226 additions and 159 deletions
+68 -17
View File
@@ -1,34 +1,85 @@
from pathlib import Path
from typing import Optional
from fastapi import APIRouter
from fastapi.responses import FileResponse
from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.templating import Jinja2Templates
from jinja2 import Environment, FileSystemLoader
from starlette.responses import Response
from ..models.schemas import Settings
router = APIRouter()
STATIC_DIR = Path(__file__).parent.parent / "static"
# Configure templates with custom delimiters to avoid conflicts
templates = Jinja2Templates(directory=str(STATIC_DIR))
templates.env = Environment(
loader=FileSystemLoader(str(STATIC_DIR)),
autoescape=True,
block_start_string="[[%",
block_end_string="%]]",
variable_start_string="[[",
variable_end_string="]]",
)
# Content type mapping for static files
CONTENT_TYPES = {
".js": "application/javascript",
".ico": "image/x-icon",
".html": "text/html",
".css": "text/css",
}
@router.get("/")
async def root():
agentic_security_path = Path(__file__).parent.parent
return FileResponse(f"{agentic_security_path}/static/index.html")
def get_static_file(filepath: Path, content_type: Optional[str] = None) -> FileResponse:
"""
Helper function to serve static files with proper error handling and caching.
Args:
filepath: Path to the static file
content_type: Optional content type override
Returns:
FileResponse with appropriate headers
Raises:
HTTPException if file not found
"""
if not filepath.is_file():
raise HTTPException(status_code=404, detail="File not found")
headers = {
"Cache-Control": "public, max-age=3600",
"Content-Type": content_type
or CONTENT_TYPES.get(filepath.suffix, "application/octet-stream"),
}
return FileResponse(filepath, headers=headers)
@router.get("/", response_class=HTMLResponse)
async def root(request: Request) -> Response:
"""Serve the main index.html template."""
return templates.TemplateResponse("index.html", {"request": request})
@router.get("/main.js")
async def main_js():
agentic_security_path = Path(__file__).parent.parent
return FileResponse(f"{agentic_security_path}/static/main.js")
async def main_js() -> FileResponse:
"""Serve the main JavaScript file."""
return get_static_file(STATIC_DIR / "main.js")
@router.get("/telemetry.js")
async def telemetry_js():
agentic_security_path = Path(__file__).parent.parent
if Settings.DISABLE_TELEMETRY:
return FileResponse(f"{agentic_security_path}/static/telemetry_disabled.js")
return FileResponse(f"{agentic_security_path}/static/telemetry.js")
async def telemetry_js() -> FileResponse:
"""
Serve either telemetry.js or telemetry_disabled.js based on settings.
"""
filename = "telemetry_disabled.js" if Settings.DISABLE_TELEMETRY else "telemetry.js"
return get_static_file(STATIC_DIR / filename)
@router.get("/favicon.ico")
async def favicon():
agentic_security_path = Path(__file__).parent.parent
return FileResponse(f"{agentic_security_path}/static/favicon.ico")
async def favicon() -> FileResponse:
"""Serve the favicon."""
return get_static_file(STATIC_DIR / "favicon.ico")
+8 -142
View File
@@ -1,46 +1,9 @@
<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LLM Vulnerability Scanner</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
<link href="https://fonts.cdnfonts.com/css/technopollas" rel="stylesheet">
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
</style>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
technopollas: ['Technopollas', 'sans-serif'],
},
colors: {
dark: {
bg: '#121212',
card: '#1E1E1E',
text: '#FFFFFF',
accent: {
green: '#4CAF50',
red: '#F44336',
orange: '#FF9800',
yellow: '#FFEB3B',
},
},
},
borderRadius: {
'lg': '1rem',
},
}
}
}
</script>
</head>
[[% block head %]]
[[% include "partials/head.html" %]]
[[% endblock head %]]
<body class="bg-dark-bg text-dark-text font-sans">
<!-- Vue app root element -->
<div id="vue-app" class="min-h-screen p-8">
@@ -68,68 +31,7 @@
</div>
</header>
<div id="consent-modal" v-if="showConsentModal"
class="fixed inset-0 bg-black bg-opacity-75 flex justify-center items-center z-50">
<div
class="bg-dark-card text-dark-text p-8 rounded-xl shadow-2xl max-w-xl w-full">
<h2 class="text-2xl font-bold mb-6 text-center">AI Red Team Ethical
Use Agreement</h2>
<div class="space-y-6">
<p class="text-sm leading-relaxed">
This AI red team tool is designed for security research,
vulnerability assessment,
and responsible testing purposes. By accessing this tool, you
explicitly agree to
the following ethical guidelines:
</p>
<ul class="list-disc list-inside text-sm space-y-3">
<li>
<strong>Consent and Authorization:</strong> You will only use
this tool on systems
for which you have explicit, documented permission from the
system owners.
</li>
<li>
<strong>Responsible Disclosure:</strong> Any vulnerabilities
discovered must be
reported responsibly to the appropriate parties, prioritizing
system and user safety.
</li>
<li>
<strong>No Malicious Intent:</strong> You will not use this tool
to cause harm,
disrupt services, or compromise the integrity of any system or
data.
</li>
<li>
<strong>Legal Compliance:</strong> All testing and research must
comply with
applicable local, national, and international laws and
regulations.
</li>
</ul>
<p class="text-xs text-gray-400 italic">
Violation of these terms may result in immediate termination of
access and
potential legal consequences.
</p>
</div>
<div class="flex justify-center space-x-4 mt-8">
<button
@click="declineConsent"
class="bg-dark-accent-red text-white rounded-lg px-6 py-3 font-medium hover:bg-opacity-80 transition-colors">
Decline
</button>
<button
@click="acceptConsent"
class="bg-dark-accent-green text-dark-bg rounded-lg px-6 py-3 font-medium hover:bg-opacity-80 transition-colors">
I Agree and Understand
</button>
</div>
</div>
</div>
[[% include "partials/concent.html" %]]
<main class="max-w-6xl mx-auto space-y-8">
<!-- Config Selection -->
@@ -503,46 +405,10 @@
</div>
</section>
</main>
<!-- Footer Section -->
<footer class="mt-16 pt-8 border-t border-gray-800">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- Column 1 -->
<div>
<h3
class="text-lg font-semibold text-dark-accent-green mb-4">Home</h3>
<p class="text-gray-400">Dedicated to LLM Security, 2024</p>
</div>
<!-- Column 2 -->
<div>
<h3
class="text-lg font-semibold text-dark-accent-green mb-4">Connect</h3>
<ul class="space-y-2">
<li><a href="https://x.com" target="_blank"
rel="noopener noreferrer"
class="text-gray-400 hover:text-dark-accent-green">X.com</a></li>
<li><a href="https://github.com/msoedov" target="_blank"
rel="noopener noreferrer"
class="text-gray-400 hover:text-dark-accent-green">Github</a></li>
</ul>
</div>
<!-- Column 3 -->
<div>
<h3
class="text-lg font-semibold text-dark-accent-green mb-4">About</h3>
<p class="text-gray-400">This is the LLM Vulnerability Scanner.
Easy to use—no coding needed, just pure security testing.</p>
</div>
</div>
<div class="mt-8 pt-8 border-t border-gray-800 text-center">
<p class="text-gray-400">Made with ❤️ by the Agentic Security
Team</p>
</div>
</div>
</footer>
[[% block footer %]]
[[% include "partials/footer.html" %]]
[[% endblock footer %]]
</div>
+1
View File
@@ -3,6 +3,7 @@ let URL = window.location.href;
if (URL.endsWith('/')) {
URL = URL.slice(0, -1);
}
URL = URL.replace('/#', '');
// Vue application
let LLM_SPECS = [
@@ -0,0 +1,67 @@
<div id="consent-modal" v-if="showConsentModal"
class="fixed inset-0 bg-black bg-opacity-75 flex justify-center items-center z-50">
<div
class="bg-dark-card text-dark-text p-8 rounded-xl shadow-2xl max-w-xl w-full">
<h2 class="text-2xl font-bold mb-6 text-center">AI Red Team Ethical
Use Agreement</h2>
<div class="space-y-6">
<p class="text-sm leading-relaxed">
This AI red team tool is designed for security research,
vulnerability assessment,
and responsible testing purposes. By accessing this tool, you
explicitly agree to
the following ethical guidelines:
</p>
<ul class="list-disc list-inside text-sm space-y-3">
<li>
<strong>Consent and Authorization:</strong> You will only
use
this tool on systems
for which you have explicit, documented permission from the
system owners.
</li>
<li>
<strong>Responsible Disclosure:</strong> Any vulnerabilities
discovered must be
reported responsibly to the appropriate parties,
prioritizing
system and user safety.
</li>
<li>
<strong>No Malicious Intent:</strong> You will not use this
tool
to cause harm,
disrupt services, or compromise the integrity of any system
or
data.
</li>
<li>
<strong>Legal Compliance:</strong> All testing and research
must
comply with
applicable local, national, and international laws and
regulations.
</li>
</ul>
<p class="text-xs text-gray-400 italic">
Violation of these terms may result in immediate termination of
access and
potential legal consequences.
</p>
</div>
<div class="flex justify-center space-x-4 mt-8">
<button
@click="declineConsent"
class="bg-dark-accent-red text-white rounded-lg px-6 py-3 font-medium hover:bg-opacity-80 transition-colors">
Decline
</button>
<button
@click="acceptConsent"
class="bg-dark-accent-green text-dark-bg rounded-lg px-6 py-3 font-medium hover:bg-opacity-80 transition-colors">
I Agree and Understand
</button>
</div>
</div>
</div>
@@ -0,0 +1,41 @@
<!-- Footer Section -->
<footer class="mt-16 pt-8 border-t border-gray-800">
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- Column 1 -->
<div>
<h3
class="text-lg font-semibold text-dark-accent-green mb-4">Home</h3>
<p class="text-gray-400">Dedicated to LLM Security, 2024</p>
</div>
<!-- Column 2 -->
<div>
<h3
class="text-lg font-semibold text-dark-accent-green mb-4">Connect</h3>
<ul class="space-y-2">
<li><a href="https://x.com" target="_blank"
rel="noopener noreferrer"
class="text-gray-400 hover:text-dark-accent-green">X.com</a></li>
<li><a href="https://github.com/msoedov" target="_blank"
rel="noopener noreferrer"
class="text-gray-400 hover:text-dark-accent-green">Github</a></li>
</ul>
</div>
<!-- Column 3 -->
<div>
<h3
class="text-lg font-semibold text-dark-accent-green mb-4">About</h3>
<p class="text-gray-400">This is the LLM Vulnerability Scanner.
Easy to use—no coding needed, just pure security
testing.</p>
</div>
</div>
<div class="mt-8 pt-8 border-t border-gray-800 text-center">
<p class="text-gray-400">Made with ❤️ by the Agentic Security
Team</p>
</div>
</div>
</footer>
@@ -0,0 +1,41 @@
<head></head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LLM Vulnerability Scanner</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
<link href="https://fonts.cdnfonts.com/css/technopollas" rel="stylesheet">
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
</style>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
technopollas: ['Technopollas', 'sans-serif'],
},
colors: {
dark: {
bg: '#121212',
card: '#1E1E1E',
text: '#FFFFFF',
accent: {
green: '#4CAF50',
red: '#F44336',
orange: '#FF9800',
yellow: '#FFEB3B',
},
},
},
borderRadius: {
'lg': '1rem',
},
}
}
}
</script>
</head>