--
This commit is contained in:
@@ -5,14 +5,26 @@
|
||||
const phaseEl = document.getElementById("tls-phase");
|
||||
const barEl = document.getElementById("tls-progress-bar");
|
||||
const logEl = document.getElementById("tls-log");
|
||||
const verbEl = document.getElementById("tls-status-verb");
|
||||
|
||||
// Colors for the severity label tag. Order Good→Bad maps to
|
||||
// bright-{green,blue,yellow,red,purple}. Matches SEVERITY_COLORS in
|
||||
// schemas.py so the live log and results page render identically.
|
||||
const SEV_COLOR = {
|
||||
good: "bright-green",
|
||||
normal: "bright-yellow",
|
||||
notgood: "bright-orange",
|
||||
normal: "bright-blue",
|
||||
notgood: "bright-yellow",
|
||||
bad: "bright-red",
|
||||
serious: "magenta",
|
||||
info: "tx",
|
||||
serious: "bright-purple",
|
||||
info: "tx-alt",
|
||||
};
|
||||
const SEV_LABEL = {
|
||||
good: "GOOD",
|
||||
normal: "NORMAL",
|
||||
notgood: "NOT GOOD",
|
||||
bad: "BAD",
|
||||
serious: "SERIOUS",
|
||||
info: "INFO",
|
||||
};
|
||||
|
||||
let reconnectAttempts = 0;
|
||||
@@ -20,25 +32,57 @@
|
||||
let ws = null;
|
||||
let closedByDone = false;
|
||||
|
||||
function appendLog(phase, detail, severity) {
|
||||
function normalizeStep(s) {
|
||||
// "handshake_sim" → "handshake-sim" for display consistency with the
|
||||
// server-rendered results page.
|
||||
return String(s || "info").replace(/_/g, "-").toLowerCase();
|
||||
}
|
||||
|
||||
function appendRow(category, body, detail, severity) {
|
||||
if (!logEl) return;
|
||||
const row = document.createElement("div");
|
||||
row.className = "tls-log-row";
|
||||
const label = document.createElement("span");
|
||||
label.className = "text-tx-alt font-small";
|
||||
label.textContent = `[${phase}] `;
|
||||
|
||||
const cat = document.createElement("span");
|
||||
cat.className = "tls-log-cat text-tx-alt";
|
||||
cat.textContent = "[" + normalizeStep(category) + "]";
|
||||
row.appendChild(cat);
|
||||
|
||||
const msg = document.createElement("span");
|
||||
msg.className = `text-${SEV_COLOR[severity] || "tx"}`;
|
||||
msg.textContent = detail || "";
|
||||
row.appendChild(label);
|
||||
msg.className = "tls-log-msg";
|
||||
if (severity && SEV_LABEL[severity] && severity !== "info") {
|
||||
const sev = document.createElement("span");
|
||||
sev.className = "text-" + (SEV_COLOR[severity] || "tx") + " font-bold";
|
||||
sev.textContent = SEV_LABEL[severity];
|
||||
msg.appendChild(sev);
|
||||
msg.appendChild(document.createTextNode(" "));
|
||||
}
|
||||
// Title is always in the default text color (white). Severity is
|
||||
// communicated by the coloured label tag, not by tinting the title.
|
||||
const msgText = document.createElement("span");
|
||||
msgText.className = "text-tx";
|
||||
msgText.textContent = body || "";
|
||||
msg.appendChild(msgText);
|
||||
row.appendChild(msg);
|
||||
|
||||
const det = document.createElement("span");
|
||||
det.className = "tls-log-detail text-tx-alt";
|
||||
det.textContent = detail || "";
|
||||
row.appendChild(det);
|
||||
|
||||
logEl.appendChild(row);
|
||||
logEl.scrollTop = logEl.scrollHeight;
|
||||
}
|
||||
|
||||
function setProgress(value, phase) {
|
||||
function setProgress(value, phaseText) {
|
||||
if (barEl) barEl.style.width = `${Math.max(0, Math.min(1, value)) * 100}%`;
|
||||
if (phaseEl && phase) phaseEl.textContent = phase;
|
||||
if (phaseEl && phaseText) phaseEl.textContent = phaseText;
|
||||
}
|
||||
|
||||
function markDone(rank, score) {
|
||||
if (verbEl) verbEl.textContent = "完了";
|
||||
if (barEl) barEl.style.width = "100%";
|
||||
if (phaseEl) phaseEl.textContent = `完了 (ランク ${rank}, スコア ${score})`;
|
||||
}
|
||||
|
||||
function connect() {
|
||||
@@ -56,7 +100,7 @@
|
||||
return;
|
||||
}
|
||||
if (msg.type === "history") {
|
||||
(msg.entries || []).forEach((e) => appendLog(e.phase, e.detail, e.severity));
|
||||
(msg.entries || []).forEach((e) => appendRow(e.phase, e.detail, "", e.severity));
|
||||
if (msg.status === "done") {
|
||||
closedByDone = true;
|
||||
location.replace(init.resultsUrl);
|
||||
@@ -64,7 +108,8 @@
|
||||
return;
|
||||
}
|
||||
if (msg.type === "progress") {
|
||||
appendLog(msg.phase, msg.detail, msg.severity);
|
||||
// Phase-level status: single body text with no detail
|
||||
appendRow(msg.phase, msg.detail, "", msg.severity);
|
||||
if (typeof msg.progress === "number") {
|
||||
setProgress(msg.progress, msg.detail || msg.phase);
|
||||
}
|
||||
@@ -72,21 +117,25 @@
|
||||
}
|
||||
if (msg.type === "finding") {
|
||||
const f = msg.finding || {};
|
||||
appendLog(f.category || "finding", `${f.severity_label || ""} ${f.title || ""} ${f.detail ? "— " + f.detail : ""}`.trim(), f.severity || "info");
|
||||
// Findings: show severity tag + title as the body, and detail in column 3.
|
||||
// The "[step]" prefix uses the phase slug (e.g. "handshake-sim")
|
||||
// rather than the coarser group ("vulnerabilities").
|
||||
const step = f.step || f.group || f.category || "info";
|
||||
appendRow(step, f.title || "", f.detail || "", f.severity || "info");
|
||||
return;
|
||||
}
|
||||
if (msg.type === "done") {
|
||||
closedByDone = true;
|
||||
setProgress(1.0, `done (rank ${msg.rank}, score ${msg.score})`);
|
||||
location.replace(msg.redirect || init.resultsUrl);
|
||||
markDone(msg.rank, msg.score);
|
||||
setTimeout(() => location.replace(msg.redirect || init.resultsUrl), 300);
|
||||
return;
|
||||
}
|
||||
if (msg.type === "error") {
|
||||
appendLog("error", msg.message || "engine failed", "serious");
|
||||
appendRow("error", msg.message || "engine failed", "", "serious");
|
||||
return;
|
||||
}
|
||||
if (msg.type === "started") {
|
||||
appendLog("started", msg.target || "", "info");
|
||||
appendRow("init", msg.target || "", "", "info");
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -101,7 +150,7 @@
|
||||
function scheduleReconnect() {
|
||||
if (closedByDone) return;
|
||||
if (reconnectAttempts >= MAX_RECONNECTS) {
|
||||
appendLog("ws", "WebSocket 接続が切断されました。ページをリロードしてください。", "bad");
|
||||
appendRow("ws", "WebSocket 接続が切断されました。ページをリロードしてください。", "", "bad");
|
||||
return;
|
||||
}
|
||||
const delay = Math.min(10_000, 1000 * Math.pow(2, reconnectAttempts));
|
||||
|
||||
Reference in New Issue
Block a user