Files
sabia/apps/gui/ui/index.html
T
Lucas df27974359 App desktop (Tauri), GitHub Actions de CI/release, elevação automática
- Move a UI de crates/sabia-cli/src/web/ para apps/gui/ui/: fonte única
  servida tanto pelo `sabia ui` quanto pelo app desktop.
- sabia-core::engine::Engine centraliza sessões de scan/monitor/update —
  usado pelo servidor local da CLI e pelo app Tauri, sem duplicar lógica.
- apps/gui/src-tauri: app desktop Tauri 2, mesma interface, comandos IPC
  espelhando a API HTTP. Pede elevação de administrador/root
  automaticamente ao abrir (modo monitor e captura crua exigem):
  manifesto requireAdministrator no Windows (UAC antes mesmo do app
  abrir), pkexec no Linux e osascript no macOS, com reinício automático
  e aviso + botão de nova tentativa na interface se for negada.
- Ícone gerado a partir do logo (apps/gui/src-tauri/icons/source.png).
- .github/workflows/ci.yml: fmt, clippy, testes (Linux/Windows/macOS),
  auditoria de dependências, compilação do app desktop.
- .github/workflows/release.yml: ao empurrar uma tag vX.Y.Z, builda a
  CLI (Linux x86_64/aarch64, macOS x86_64/aarch64, Windows x86_64) e o
  app desktop pras mesmas plataformas, publica tudo numa release do
  GitHub com checksums SHA-256.
- sabia-core::update: corrige o nome do asset esperado (casava pelo
  nome fixo, mas o release empacota com a versão no nome) e a extração
  (tar.gz no Linux/macOS, zip no Windows).
- LICENSE-MIT, LICENSE-APACHE, CHANGELOG.md com a entrada 0.1.0.
- cargo fmt + clippy (-D warnings) limpos em todo o workspace.
2026-10-23 08:56:08 -03:00

77 lines
3.0 KiB
HTML

<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sabiá</title>
<link rel="icon" href="/sabia-logo.svg">
<link rel="stylesheet" href="/app.css">
</head>
<body>
<div class="app">
<aside class="sidebar">
<div class="brand">
<img src="/sabia-logo.svg" alt="">
<div>
<strong>Sabiá</strong>
<small>auditoria de Wi-Fi</small>
</div>
</div>
<div class="side-title">Interfaces</div>
<ul class="list" id="ifaceList" data-empty="nenhuma interface Wi-Fi encontrada"></ul>
<div class="side-foot">
<span id="verInfo" class="mono">—</span>
<button id="btnUpdate" type="button">checar atualização</button>
</div>
</aside>
<main class="main">
<div class="page">
<div class="topbar">
<div>
<h1>Painel de captura</h1>
<div class="sub" id="ifaceSub">selecione uma interface</div>
</div>
<span id="modePill" class="pill"><span class="dot"></span><span id="modeLabel">—</span></span>
</div>
<svg class="wave" id="wave" viewBox="0 0 600 34" preserveAspectRatio="none">
<path class="flat" d="M0 17 L600 17"/>
<path class="live" id="waveLive" d="M0 17 L600 17"/>
</svg>
<div class="notice" id="elevateNotice" hidden>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
<span id="elevateMsg">Pedindo privilégio de administrador — necessário pra modo monitor e captura…</span>
<button id="btnElevateRetry" class="btn" style="margin-left:auto" hidden>tentar de novo</button>
</div>
<div class="notice">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
<span>Use somente em redes próprias ou com autorização explícita do responsável. Toda ativação de modo monitor e sessão de captura fica registrada na trilha de auditoria local.</span>
</div>
<div class="controls">
<div class="group">
<button id="btnMonitor" class="btn" disabled>ativar modo monitor</button>
</div>
<div class="group">
<button id="btnScan" class="btn primary" disabled>iniciar captura</button>
</div>
</div>
<div class="result-head">
<strong>Redes vistas</strong>
<span id="count">0</span>
</div>
<div id="resultArea"></div>
</div>
</main>
</div>
<script src="/app.js"></script>
</body>
</html>