feat: pentest onboarding — streaming, browser automation, reports, user cleanup (#16)
Complete pentest feature overhaul: SSE streaming, session-persistent browser tool (CDP), AES-256 credential encryption, auto-screenshots in reports, code-level remediation correlation, SAST triage chunking, context window optimization, test user cleanup (Keycloak/Auth0/Okta), wizard dropdowns, attack chain improvements, architecture docs with Mermaid diagrams. Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com> Reviewed-on: #16
This commit was merged in pull request #16.
This commit is contained in:
@@ -7,6 +7,7 @@ use crate::components::attack_chain::AttackChainView;
|
||||
use crate::components::severity_badge::SeverityBadge;
|
||||
use crate::infrastructure::pentest::{
|
||||
export_pentest_report, fetch_attack_chain, fetch_pentest_findings, fetch_pentest_session,
|
||||
pause_pentest_session, resume_pentest_session,
|
||||
};
|
||||
|
||||
#[component]
|
||||
@@ -87,11 +88,13 @@ pub fn PentestSessionPage(session_id: String) -> Element {
|
||||
};
|
||||
|
||||
let is_running = session_status == "running";
|
||||
let is_paused = session_status == "paused";
|
||||
let is_active = is_running || is_paused;
|
||||
|
||||
// Poll while running
|
||||
// Poll while running or paused
|
||||
use_effect(move || {
|
||||
let _gen = *poll_gen.read();
|
||||
if is_running {
|
||||
if is_active {
|
||||
spawn(async move {
|
||||
#[cfg(feature = "web")]
|
||||
gloo_timers::future::TimeoutFuture::new(3_000).await;
|
||||
@@ -226,9 +229,55 @@ pub fn PentestSessionPage(session_id: String) -> Element {
|
||||
" Running..."
|
||||
}
|
||||
}
|
||||
if is_paused {
|
||||
span { style: "font-size: 0.8rem; color: #d97706;",
|
||||
Icon { icon: BsPauseCircle, width: 12, height: 12 }
|
||||
" Paused"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
div { style: "display: flex; gap: 8px;",
|
||||
if is_running {
|
||||
{
|
||||
let sid_pause = session_id.clone();
|
||||
rsx! {
|
||||
button {
|
||||
class: "btn btn-ghost",
|
||||
style: "font-size: 0.85rem; color: #d97706; border-color: #d97706;",
|
||||
onclick: move |_| {
|
||||
let sid = sid_pause.clone();
|
||||
spawn(async move {
|
||||
let _ = pause_pentest_session(sid).await;
|
||||
session.restart();
|
||||
});
|
||||
},
|
||||
Icon { icon: BsPauseCircle, width: 14, height: 14 }
|
||||
" Pause"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_paused {
|
||||
{
|
||||
let sid_resume = session_id.clone();
|
||||
rsx! {
|
||||
button {
|
||||
class: "btn btn-ghost",
|
||||
style: "font-size: 0.85rem; color: #16a34a; border-color: #16a34a;",
|
||||
onclick: move |_| {
|
||||
let sid = sid_resume.clone();
|
||||
spawn(async move {
|
||||
let _ = resume_pentest_session(sid).await;
|
||||
session.restart();
|
||||
});
|
||||
},
|
||||
Icon { icon: BsPlayCircle, width: 14, height: 14 }
|
||||
" Resume"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
button {
|
||||
class: "btn btn-primary",
|
||||
style: "font-size: 0.85rem;",
|
||||
|
||||
Reference in New Issue
Block a user