TafadzwaTaps commited on
Commit
8ef8aee
·
1 Parent(s): 2630621

latest deployment

Browse files
Files changed (3) hide show
  1. app.py +23 -23
  2. frontend/api.js +19 -15
  3. frontend/app.js +23 -18
app.py CHANGED
@@ -246,7 +246,6 @@ def scan_vulnerabilities(text: str):
246
  # AI ENGINE
247
  # =========================================================
248
  async def ai_enrich(text: str, findings):
249
- # 🔒 No API key fallback
250
  if not HF_API_KEY:
251
  return {
252
  "explanation": "AI disabled",
@@ -262,19 +261,24 @@ async def ai_enrich(text: str, findings):
262
  "inputs": f"""
263
  You are a cybersecurity expert.
264
 
 
 
 
 
 
 
 
 
265
  Findings:
266
  {findings}
267
 
268
- Return STRICT JSON ONLY:
269
- {{ "explanation": "", "fixes": [] }}
270
-
271
  Code:
272
- {text[:2000]}
273
  """
274
  }
275
  )
276
 
277
- # 🔥 STEP 1: SAFE PARSE
278
  try:
279
  data = res.json()
280
  except Exception as e:
@@ -282,15 +286,15 @@ Code:
282
  print("RAW RESPONSE:", res.text)
283
 
284
  return {
285
- "explanation": "AI returned invalid response",
286
  "fixes": []
287
  }
288
 
289
- # 🔥 STEP 2: HANDLE HF FORMAT
290
  if isinstance(data, list):
291
  data = data[0]
292
 
293
- # 🔥 STEP 3: HANDLE STRING OUTPUT (VERY COMMON)
294
  if isinstance(data, dict) and "generated_text" in data:
295
  text_output = data["generated_text"]
296
 
@@ -300,15 +304,13 @@ Code:
300
  return parsed
301
  except:
302
  return {
303
- "explanation": text_output,
304
  "fixes": []
305
  }
306
 
307
- # 🔥 STEP 4: VALID DICT
308
  if isinstance(data, dict):
309
  return data
310
 
311
- # 🔥 STEP 5: FALLBACK
312
  return {
313
  "explanation": str(data),
314
  "fixes": []
@@ -316,7 +318,6 @@ Code:
316
 
317
  except Exception as e:
318
  print("🔥 AI REQUEST ERROR:", str(e))
319
-
320
  return {
321
  "explanation": "AI request failed",
322
  "fixes": []
@@ -341,16 +342,7 @@ async def analyze(req: AnalyzeRequest, auth=Depends(get_user)):
341
 
342
  findings = scan_vulnerabilities(req.text)
343
 
344
- # SAFE AI
345
- ai_raw = await ai_enrich(req.text, findings)
346
-
347
- if isinstance(ai_raw, dict):
348
- ai = ai_raw
349
- else:
350
- ai = {
351
- "explanation": str(ai_raw),
352
- "fixes": []
353
- }
354
 
355
  analysis_id = str(uuid.uuid4())
356
 
@@ -400,6 +392,14 @@ def usage(auth=Depends(get_user)):
400
  def home():
401
  return {"status": "SafeAIScan running on Hugging Face Spaces"}
402
 
 
 
 
 
 
 
 
 
403
  @app.get("/api/history")
404
  def history(auth=Depends(get_user)):
405
  user = auth["user"]
 
246
  # AI ENGINE
247
  # =========================================================
248
  async def ai_enrich(text: str, findings):
 
249
  if not HF_API_KEY:
250
  return {
251
  "explanation": "AI disabled",
 
261
  "inputs": f"""
262
  You are a cybersecurity expert.
263
 
264
+ Analyze this code and return ONLY valid JSON.
265
+
266
+ Format:
267
+ {{ "explanation": "string", "fixes": ["string"] }}
268
+
269
+ Do not include markdown.
270
+ Do not include text outside JSON.
271
+
272
  Findings:
273
  {findings}
274
 
 
 
 
275
  Code:
276
+ {text[:1500]}
277
  """
278
  }
279
  )
280
 
281
+ # SAFE PARSE
282
  try:
283
  data = res.json()
284
  except Exception as e:
 
286
  print("RAW RESPONSE:", res.text)
287
 
288
  return {
289
+ "explanation": res.text[:500],
290
  "fixes": []
291
  }
292
 
293
+ # HANDLE HF FORMAT
294
  if isinstance(data, list):
295
  data = data[0]
296
 
297
+ # HANDLE GENERATED TEXT
298
  if isinstance(data, dict) and "generated_text" in data:
299
  text_output = data["generated_text"]
300
 
 
304
  return parsed
305
  except:
306
  return {
307
+ "explanation": text_output[:500],
308
  "fixes": []
309
  }
310
 
 
311
  if isinstance(data, dict):
312
  return data
313
 
 
314
  return {
315
  "explanation": str(data),
316
  "fixes": []
 
318
 
319
  except Exception as e:
320
  print("🔥 AI REQUEST ERROR:", str(e))
 
321
  return {
322
  "explanation": "AI request failed",
323
  "fixes": []
 
342
 
343
  findings = scan_vulnerabilities(req.text)
344
 
345
+ ai = await ai_enrich(req.text, findings)
 
 
 
 
 
 
 
 
 
346
 
347
  analysis_id = str(uuid.uuid4())
348
 
 
392
  def home():
393
  return {"status": "SafeAIScan running on Hugging Face Spaces"}
394
 
395
+ @app.get("/api/me")
396
+ def get_me(auth=Depends(get_user)):
397
+ user = auth["user"]
398
+
399
+ return {
400
+ "plan": user.get("plan", "free")
401
+ }
402
+
403
  @app.get("/api/history")
404
  def history(auth=Depends(get_user)):
405
  user = auth["user"]
frontend/api.js CHANGED
@@ -1,11 +1,5 @@
1
- // =========================
2
- // CONFIG
3
- // =========================
4
  const BASE_URL = "https://rathious-safeaiscan.hf.space";
5
 
6
- // =========================
7
- // TOKEN HELPERS
8
- // =========================
9
  function getToken() {
10
  return localStorage.getItem("access_token");
11
  }
@@ -19,9 +13,6 @@ function clearAuth() {
19
  window.location.replace("login.html");
20
  }
21
 
22
- // =========================
23
- // CORE REQUEST WRAPPER
24
- // =========================
25
  async function apiRequest(endpoint, options = {}) {
26
  const res = await fetch(BASE_URL + endpoint, {
27
  ...options,
@@ -36,7 +27,6 @@ async function apiRequest(endpoint, options = {}) {
36
  });
37
 
38
  if (res.status === 401) {
39
- console.warn("Session expired");
40
  clearAuth();
41
  return null;
42
  }
@@ -44,9 +34,18 @@ async function apiRequest(endpoint, options = {}) {
44
  return res;
45
  }
46
 
47
- // =========================
48
- // API FUNCTIONS
49
- // =========================
 
 
 
 
 
 
 
 
 
50
  async function analyzeCode(text) {
51
  const res = await apiRequest("/api/analyze", {
52
  method: "POST",
@@ -65,10 +64,15 @@ async function analyzeCode(text) {
65
 
66
  async function getUsage() {
67
  const res = await apiRequest("/api/usage");
68
- return res.json();
69
  }
70
 
71
  async function getHistory() {
72
  const res = await apiRequest("/api/history");
73
- return res.json();
 
 
 
 
 
74
  }
 
 
 
 
1
  const BASE_URL = "https://rathious-safeaiscan.hf.space";
2
 
 
 
 
3
  function getToken() {
4
  return localStorage.getItem("access_token");
5
  }
 
13
  window.location.replace("login.html");
14
  }
15
 
 
 
 
16
  async function apiRequest(endpoint, options = {}) {
17
  const res = await fetch(BASE_URL + endpoint, {
18
  ...options,
 
27
  });
28
 
29
  if (res.status === 401) {
 
30
  clearAuth();
31
  return null;
32
  }
 
34
  return res;
35
  }
36
 
37
+ // SAFE JSON PARSE
38
+ async function safeJson(res) {
39
+ const text = await res.text();
40
+ try {
41
+ return JSON.parse(text);
42
+ } catch {
43
+ console.error("RAW ERROR:", text);
44
+ throw new Error("Server error: " + text);
45
+ }
46
+ }
47
+
48
+ // API CALLS
49
  async function analyzeCode(text) {
50
  const res = await apiRequest("/api/analyze", {
51
  method: "POST",
 
64
 
65
  async function getUsage() {
66
  const res = await apiRequest("/api/usage");
67
+ return safeJson(res);
68
  }
69
 
70
  async function getHistory() {
71
  const res = await apiRequest("/api/history");
72
+ return safeJson(res);
73
+ }
74
+
75
+ async function getMe() {
76
+ const res = await apiRequest("/api/me");
77
+ return safeJson(res);
78
  }
frontend/app.js CHANGED
@@ -1,7 +1,3 @@
1
- // =========================
2
- // UI ACTIONS
3
- // =========================
4
-
5
  async function scan() {
6
  const code = document.getElementById("code").value;
7
 
@@ -11,6 +7,11 @@ async function scan() {
11
  document.getElementById("result").innerText =
12
  JSON.stringify(data, null, 2);
13
 
 
 
 
 
 
14
  } catch (err) {
15
  console.error(err);
16
  alert("Scan failed");
@@ -38,17 +39,26 @@ async function loadHistory() {
38
  try {
39
  const data = await getHistory();
40
 
41
- const historyList = document.getElementById("history");
42
- historyList.innerHTML = "";
43
 
44
  data.forEach(item => {
45
  const li = document.createElement("li");
46
  li.innerText = item.risk + " (" + item.score + ")";
47
- historyList.appendChild(li);
48
  });
49
 
50
  } catch (err) {
51
- console.error("History failed", err);
 
 
 
 
 
 
 
 
 
52
  }
53
  }
54
 
@@ -56,12 +66,12 @@ function copyKey() {
56
  const key = localStorage.getItem("api_key");
57
 
58
  if (!key) {
59
- alert("No API key found");
60
  return;
61
  }
62
 
63
  navigator.clipboard.writeText(key);
64
- alert("API key copied!");
65
  }
66
 
67
  function logout() {
@@ -69,24 +79,19 @@ function logout() {
69
  window.location.replace("login.html");
70
  }
71
 
72
- // =========================
73
  // INIT
74
- // =========================
75
  async function init() {
76
- // Show API key
77
- const apiKey = localStorage.getItem("api_key");
78
  document.getElementById("apiKey").innerText =
79
- apiKey || "Not available";
80
 
81
  await loadUsage();
82
  await loadHistory();
 
83
  }
84
 
85
  init();
86
 
87
- // =========================
88
- // MAKE FUNCTIONS GLOBAL (IMPORTANT)
89
- // =========================
90
  window.scan = scan;
91
  window.copyKey = copyKey;
92
  window.logout = logout;
 
 
 
 
 
1
  async function scan() {
2
  const code = document.getElementById("code").value;
3
 
 
7
  document.getElementById("result").innerText =
8
  JSON.stringify(data, null, 2);
9
 
10
+ // ✅ LIVE USAGE UPDATE
11
+ if (data.usage_today !== undefined) {
12
+ document.getElementById("usage").innerText = data.usage_today;
13
+ }
14
+
15
  } catch (err) {
16
  console.error(err);
17
  alert("Scan failed");
 
39
  try {
40
  const data = await getHistory();
41
 
42
+ const list = document.getElementById("history");
43
+ list.innerHTML = "";
44
 
45
  data.forEach(item => {
46
  const li = document.createElement("li");
47
  li.innerText = item.risk + " (" + item.score + ")";
48
+ list.appendChild(li);
49
  });
50
 
51
  } catch (err) {
52
+ console.error(err);
53
+ }
54
+ }
55
+
56
+ async function loadPlan() {
57
+ try {
58
+ const data = await getMe();
59
+ document.getElementById("plan").innerText = data.plan;
60
+ } catch {
61
+ document.getElementById("plan").innerText = "Free";
62
  }
63
  }
64
 
 
66
  const key = localStorage.getItem("api_key");
67
 
68
  if (!key) {
69
+ alert("No API key");
70
  return;
71
  }
72
 
73
  navigator.clipboard.writeText(key);
74
+ alert("Copied!");
75
  }
76
 
77
  function logout() {
 
79
  window.location.replace("login.html");
80
  }
81
 
 
82
  // INIT
 
83
  async function init() {
 
 
84
  document.getElementById("apiKey").innerText =
85
+ localStorage.getItem("api_key") || "Not available";
86
 
87
  await loadUsage();
88
  await loadHistory();
89
+ await loadPlan();
90
  }
91
 
92
  init();
93
 
94
+ // 🔥 REQUIRED FOR BUTTONS
 
 
95
  window.scan = scan;
96
  window.copyKey = copyKey;
97
  window.logout = logout;