dn-scribe commited on
Commit
8d23865
·
unverified ·
1 Parent(s): ee528c1

feat: favicon + copy paste + open links in new tabs

Browse files
app/main.py CHANGED
@@ -37,7 +37,7 @@ app = FastAPI()
37
  templates = Jinja2Templates(directory="app/templates")
38
 
39
 
40
- from fastapi.responses import PlainTextResponse, HTMLResponse
41
 
42
  # # Add a helper function to validate CVE-ID
43
  # def validate_cve_id(cve_id: str):
@@ -236,6 +236,17 @@ async def ghsa_to_cve_endpoint(ghsa_id: str):
236
  raise HTTPException(status_code=500, detail="Internal server error.")
237
 
238
 
 
 
 
 
 
 
 
 
 
 
 
239
  mcp = FastApiMCP(
240
  app,
241
  name="Get CVE Info", # Name for your MCP server
 
37
  templates = Jinja2Templates(directory="app/templates")
38
 
39
 
40
+ from fastapi.responses import PlainTextResponse, HTMLResponse, FileResponse
41
 
42
  # # Add a helper function to validate CVE-ID
43
  # def validate_cve_id(cve_id: str):
 
236
  raise HTTPException(status_code=500, detail="Internal server error.")
237
 
238
 
239
+ @app.get("/favicon.ico", include_in_schema=False)
240
+ def favicon():
241
+ """
242
+ Endpoint to serve the favicon.
243
+
244
+ Returns:
245
+ FileResponse: The favicon image file.
246
+ """
247
+ return FileResponse("app/templates/favicon.png")
248
+
249
+
250
  mcp = FastApiMCP(
251
  app,
252
  name="Get CVE Info", # Name for your MCP server
app/templates/favicon.png ADDED
app/templates/index.html CHANGED
@@ -36,11 +36,38 @@
36
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
37
  </head>
38
  <body>
 
39
  <h2>🛡️ CVE Report</h2>
40
  <div id="spinner">⏳ Loading report...</div>
41
  <div id="output"></div>
 
42
 
43
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  document.addEventListener("DOMContentLoaded", async () => {
45
  const params = new URLSearchParams(window.location.search);
46
  const cveId = params.get("cve_id");
@@ -60,6 +87,14 @@
60
  const text = await res.text();
61
  spinnerEl.style.display = "none";
62
  outputEl.innerHTML = marked.parse(text);
 
 
 
 
 
 
 
 
63
  outputEl.style.display = "block";
64
  } catch {
65
  startStreaming();
@@ -74,6 +109,14 @@
74
  evtSource.onmessage = (e) => {
75
  buffer += e.data;
76
  outputEl.innerHTML = marked.parse(buffer);
 
 
 
 
 
 
 
 
77
  outputEl.style.display = "block";
78
  outputEl.scrollTop = outputEl.scrollHeight;
79
  };
@@ -83,6 +126,14 @@
83
  buffer += e.data;
84
  spinnerEl.style.display = "none";
85
  outputEl.innerHTML = marked.parse(buffer);
 
 
 
 
 
 
 
 
86
  outputEl.scrollTop = outputEl.scrollHeight;
87
  });
88
 
 
36
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
37
  </head>
38
  <body>
39
+ <button id="copyTop" style="position: absolute; top: 10px; left: 10px;">Copy</button>
40
  <h2>🛡️ CVE Report</h2>
41
  <div id="spinner">⏳ Loading report...</div>
42
  <div id="output"></div>
43
+ <button id="copyBottom" style="position: absolute; bottom: 10px; left: 10px;">Copy</button>
44
 
45
  <script>
46
+ function copyToClipboard() {
47
+ const outputEl = document.getElementById("output");
48
+ const text = outputEl.innerHTML.replace(/<h1>(.*?)<\/h1>/g, '# $1')
49
+ .replace(/<h2>(.*?)<\/h2>/g, '## $1')
50
+ .replace(/<h3>(.*?)<\/h3>/g, '### $1')
51
+ .replace(/<h4>(.*?)<\/h4>/g, '#### $1')
52
+ .replace(/<h5>(.*?)<\/h5>/g, '##### $1')
53
+ .replace(/<h6>(.*?)<\/h6>/g, '###### $1')
54
+ .replace(/<strong>(.*?)<\/strong>/g, '**$1**')
55
+ .replace(/<em>(.*?)<\/em>/g, '*$1*')
56
+ .replace(/<ul>/g, '\n')
57
+ .replace(/<li>(.*?)<\/li>/g, '- $1')
58
+ .replace(/<\/ul>/g, '\n')
59
+ .replace(/<br\s*\/?>/g, '\n')
60
+ .replace(/<[^>]+>/g, ''); // Remove other HTML tags
61
+ navigator.clipboard.writeText(text).then(() => {
62
+ alert("Content copied to clipboard!");
63
+ }).catch(err => {
64
+ console.error("Failed to copy content: ", err);
65
+ });
66
+ }
67
+
68
+ document.getElementById("copyTop").addEventListener("click", copyToClipboard);
69
+ document.getElementById("copyBottom").addEventListener("click", copyToClipboard);
70
+
71
  document.addEventListener("DOMContentLoaded", async () => {
72
  const params = new URLSearchParams(window.location.search);
73
  const cveId = params.get("cve_id");
 
87
  const text = await res.text();
88
  spinnerEl.style.display = "none";
89
  outputEl.innerHTML = marked.parse(text);
90
+
91
+ // Ensure links open in a new tab
92
+ const links = outputEl.querySelectorAll("a");
93
+ links.forEach(link => {
94
+ link.setAttribute("target", "_blank");
95
+ link.setAttribute("rel", "noopener noreferrer");
96
+ });
97
+
98
  outputEl.style.display = "block";
99
  } catch {
100
  startStreaming();
 
109
  evtSource.onmessage = (e) => {
110
  buffer += e.data;
111
  outputEl.innerHTML = marked.parse(buffer);
112
+
113
+ // Ensure links open in a new tab
114
+ const links = outputEl.querySelectorAll("a");
115
+ links.forEach(link => {
116
+ link.setAttribute("target", "_blank");
117
+ link.setAttribute("rel", "noopener noreferrer");
118
+ });
119
+
120
  outputEl.style.display = "block";
121
  outputEl.scrollTop = outputEl.scrollHeight;
122
  };
 
126
  buffer += e.data;
127
  spinnerEl.style.display = "none";
128
  outputEl.innerHTML = marked.parse(buffer);
129
+
130
+ // Ensure links open in a new tab
131
+ const links = outputEl.querySelectorAll("a");
132
+ links.forEach(link => {
133
+ link.setAttribute("target", "_blank");
134
+ link.setAttribute("rel", "noopener noreferrer");
135
+ });
136
+
137
  outputEl.scrollTop = outputEl.scrollHeight;
138
  });
139
 
app/tmp.md ADDED
File without changes