Files
armeech-neptune/frontend/index.html
T
janis b69e603791
Deploy / deploy (push) Successful in 38s
adding download helper and viewer
2026-05-12 10:08:17 +02:00

566 lines
32 KiB
HTML

<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Neptune - Cybersecurity Incident Journal</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.1/css/all.min.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark border-bottom border-secondary">
<div class="container-fluid">
<a class="navbar-brand d-flex align-items-center" href="#">
<i class="fas fa-globe me-2 text-primary"></i>
<span class="fw-bold">Neptune</span>
<span class="badge bg-secondary ms-2 small">Cybersecurity Journal</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="nav nav-tabs border-0 ms-3" id="mainTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="timeline-tab" data-bs-toggle="tab" data-bs-target="#timeline" type="button" role="tab">
<i class="fas fa-clock me-1"></i>Timeline
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="network-tab" data-bs-toggle="tab" data-bs-target="#network" type="button" role="tab">
<i class="fas fa-project-diagram me-1"></i>Network Map
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="documents-tab" data-bs-toggle="tab" data-bs-target="#documents" type="button" role="tab">
<i class="fas fa-file-alt me-1"></i>Documents
</button>
</li>
</ul>
<div class="ms-auto d-flex align-items-center">
<span class="text-secondary small me-2" id="userDisplay"></span>
<button class="btn btn-outline-secondary btn-sm me-2 d-none" id="settingsBtn" data-bs-toggle="modal" data-bs-target="#settingsModal" title="Settings"><i class="fas fa-cog"></i></button>
<button class="btn btn-outline-secondary btn-sm" id="logoutBtn"><i class="fas fa-sign-out-alt"></i></button>
</div>
</div>
</div>
</nav>
<div class="container-fluid mt-3">
<div class="tab-content" id="mainTabContent">
<div class="tab-pane fade show active" id="timeline" role="tabpanel">
<div class="row mb-3">
<div class="col-md-6">
<h4><i class="fas fa-clock text-primary"></i> Incident Timeline</h4>
</div>
<div class="col-md-6 text-end">
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#eventModal">
<i class="fas fa-plus me-1"></i> New Event
</button>
</div>
</div>
<div class="row mb-3">
<div class="col-md-3">
<select class="form-select form-select-sm" id="teamFilter">
<option value="">All Teams</option>
</select>
</div>
<div class="col-md-3">
<select class="form-select form-select-sm" id="tagFilter">
<option value="">All Tags</option>
</select>
</div>
<div class="col-md-6">
<input type="text" class="form-control form-control-sm" id="searchEvents" placeholder="Search events...">
</div>
</div>
<div id="timelineContainer">
<div class="text-center text-secondary py-5">
<div class="spinner-border" role="status"></div>
<p class="mt-2">Loading events...</p>
</div>
</div>
</div>
<div class="tab-pane fade" id="network" role="tabpanel">
<div class="row mb-3">
<div class="col-md-6">
<h4><i class="fas fa-project-diagram text-primary"></i> Network Map</h4>
<small class="text-secondary">Drag nodes & shapes &middot; Resize via corner handles &middot; <kbd class="bg-dark text-secondary">Del</kbd> to delete</small>
</div>
<div class="col-md-6 text-end">
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#nodeModal">
<i class="fas fa-plus me-1"></i> Add Node
</button>
<button class="btn btn-info btn-sm text-dark" data-bs-toggle="modal" data-bs-target="#shapeModal">
<i class="fas fa-vector-square me-1"></i> Add Shape
</button>
<button class="btn btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#linkModal">
<i class="fas fa-link me-1"></i> Add Link
</button>
</div>
</div>
<div class="row">
<div class="col-md-9">
<div class="card bg-dark border-secondary">
<div class="card-body p-0" id="networkCanvasWrapper" style="height: 70vh; position: relative; overflow: hidden;">
<canvas id="networkCanvas" style="width: 100%; height: 100%;"></canvas>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-dark border-secondary mb-2">
<div class="card-header py-2">
<small class="fw-bold"><i class="fas fa-info-circle me-1"></i> Details</small>
</div>
<div class="card-body py-2" id="nodeDetails">
<small class="text-secondary">Click a node or shape</small>
</div>
</div>
<ul class="nav nav-pills nav-fill mb-2 gap-1" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active py-1 small" id="nodes-tab" data-bs-toggle="tab" data-bs-target="#nodesPanel" type="button">
<i class="fas fa-desktop me-1"></i> Nodes
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link py-1 small" id="shapes-tab" data-bs-toggle="tab" data-bs-target="#shapesPanel" type="button">
<i class="fas fa-vector-square me-1"></i> Shapes
</button>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="nodesPanel">
<div class="list-group list-group-flush bg-dark border-secondary rounded" id="nodeList" style="max-height: 35vh; overflow-y: auto;"></div>
</div>
<div class="tab-pane fade" id="shapesPanel">
<div class="list-group list-group-flush bg-dark border-secondary rounded" id="shapeList" style="max-height: 35vh; overflow-y: auto;"></div>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="documents" role="tabpanel">
<div class="row mb-3">
<div class="col-md-6">
<h4><i class="fas fa-file-alt text-primary"></i> Documents</h4>
<small class="text-secondary">Standardized forms for deployments, attacks, incident reports & more</small>
</div>
<div class="col-md-6 text-end">
<div class="btn-group btn-group-sm">
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#documentModal">
<i class="fas fa-plus me-1"></i> New Document
</button>
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown"></button>
<ul class="dropdown-menu dropdown-menu-end bg-dark border-secondary">
<li><a class="dropdown-item small" href="#" onclick="openNewDocument('deployment')"><i class="fas fa-server me-2 text-info"></i>Deployment</a></li>
<li><a class="dropdown-item small" href="#" onclick="openNewDocument('attack')"><i class="fas fa-bolt me-2 text-danger"></i>Attack</a></li>
<li><a class="dropdown-item small" href="#" onclick="openNewDocument('incident-report')"><i class="fas fa-exclamation-triangle me-2 text-warning"></i>Incident Report</a></li>
<li><a class="dropdown-item small" href="#" onclick="openNewDocument('remediation')"><i class="fas fa-wrench me-2 text-success"></i>Remediation</a></li>
<li><a class="dropdown-item small" href="#" onclick="openNewDocument('exercise')"><i class="fas fa-dumbbell me-2 text-primary"></i>Exercise</a></li>
</ul>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-4">
<select class="form-select form-select-sm" id="docTeamFilter">
<option value="">All Teams</option>
</select>
</div>
<div class="col-md-4">
<select class="form-select form-select-sm" id="docTypeFilter">
<option value="">All Types</option>
<option value="deployment">Deployment</option>
<option value="attack">Attack</option>
<option value="incident-report">Incident Report</option>
<option value="remediation">Remediation</option>
<option value="exercise">Exercise</option>
</select>
</div>
<div class="col-md-4">
<input type="text" class="form-control form-control-sm" id="searchDocs" placeholder="Search documents...">
</div>
</div>
<div id="documentContainer">
<div class="text-center text-secondary py-5">
<div class="spinner-border" role="status"></div>
<p class="mt-2">Loading documents...</p>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="eventModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-plus-circle text-primary me-1"></i> New Event</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="eventForm">
<div class="mb-2">
<label class="form-label small">Team</label>
<select class="form-select form-select-sm" id="eventTeam" required></select>
</div>
<div class="mb-2">
<label class="form-label small">Title</label>
<input type="text" class="form-control form-control-sm" id="eventTitle" required>
</div>
<div class="mb-2">
<label class="form-label small">Description</label>
<textarea class="form-control form-control-sm" id="eventDescription" rows="3"></textarea>
</div>
<div class="row mb-2">
<div class="col">
<label class="form-label small">Severity</label>
<select class="form-select form-select-sm" id="eventSeverity">
<option value="info">Info</option>
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
<option value="critical">Critical</option>
</select>
</div>
<div class="col">
<label class="form-label small">Type</label>
<select class="form-select form-select-sm" id="eventType">
<option value="general">General</option>
<option value="detection">Detection</option>
<option value="incident">Incident</option>
<option value="remediation">Remediation</option>
<option value="intel">Threat Intel</option>
<option value="exercise">Exercise</option>
</select>
</div>
</div>
<div class="mb-2">
<label class="form-label small">Tags</label>
<input type="text" class="form-control form-control-sm" id="eventTagsInput" placeholder="e.g. phishing, ransomware, ioc">
<small class="text-secondary">Comma-separated tags</small>
<div id="eventTagsDisplay" class="d-flex flex-wrap gap-1 mt-1"></div>
</div>
<div class="mb-2">
<label class="form-label small">File Attachments</label>
<input type="file" class="form-control form-control-sm" id="eventFileInput" multiple accept=".pdf,.md,.txt,.docx,.xlsx,.csv,.pptx,.evidence">
<div id="eventFilePreview" class="mt-1"></div>
</div>
</form>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-primary" id="saveEvent"><i class="fas fa-save me-1"></i> Save Event</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="nodeModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-desktop text-primary me-1"></i> <span id="nodeModalLabel">Add Network Node</span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="nodeForm">
<div class="mb-2">
<label class="form-label small">Label</label>
<input type="text" class="form-control form-control-sm" id="nodeLabel" required>
</div>
<div class="mb-2">
<label class="form-label small">IP Address</label>
<input type="text" class="form-control form-control-sm" id="nodeIp">
</div>
<div class="row mb-2">
<div class="col">
<label class="form-label small">Type</label>
<select class="form-select form-select-sm" id="nodeType">
<option value="host">Host</option>
<option value="server">Server</option>
<option value="router">Router</option>
<option value="firewall">Firewall</option>
<option value="switch">Switch</option>
<option value="cloud">Cloud</option>
<option value="endpoint">Endpoint</option>
<option value="other">Other</option>
</select>
</div>
<div class="col">
<label class="form-label small">Status</label>
<select class="form-select form-select-sm" id="nodeStatus">
<option value="unknown">Unknown</option>
<option value="online">Online</option>
<option value="offline">Offline</option>
<option value="monitoring">Monitoring</option>
<option value="compromised">Compromised</option>
</select>
</div>
</div>
<div class="mb-2">
<label class="form-label small">Group</label>
<input type="text" class="form-control form-control-sm" id="nodeGroup" placeholder="e.g. DMZ, Internal, Cloud">
</div>
<div class="mb-2">
<label class="form-label small">Notes</label>
<textarea class="form-control form-control-sm" id="nodeNotes" rows="2" placeholder="Tags, descriptions, vulnerabilities..."></textarea>
</div>
</form>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-primary" id="saveNode"><i class="fas fa-save me-1"></i> Add Node</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="shapeModal" tabindex="-1">
<div class="modal-dialog modal-sm">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-vector-square text-info me-1"></i> <span id="shapeModalLabel">Add Shape</span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="shapeForm">
<div class="mb-2">
<label class="form-label small">Label</label>
<input type="text" class="form-control form-control-sm" id="shapeLabel" placeholder="DMZ, Internal Net, ...">
</div>
<div class="mb-2">
<label class="form-label small">Type</label>
<select class="form-select form-select-sm" id="shapeType">
<option value="rectangle">Rectangle / Box</option>
<option value="ellipse">Ellipse</option>
</select>
</div>
<div class="row mb-2">
<div class="col">
<label class="form-label small">Fill</label>
<input type="color" class="form-control form-control-color form-control-sm" id="shapeColor" value="#1e3a5f">
</div>
<div class="col">
<label class="form-label small">Border</label>
<input type="color" class="form-control form-control-color form-control-sm" id="shapeBorderColor" value="#3b82f6">
</div>
</div>
<div class="mb-2">
<label class="form-label small">Opacity <span id="opacityVal">0.15</span></label>
<input type="range" class="form-range" id="shapeOpacity" min="0.05" max="0.5" step="0.05" value="0.15">
</div>
</form>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-primary" id="saveShape"><i class="fas fa-save me-1"></i> Add Shape</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="linkModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-link text-primary me-1"></i> Add Connection</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="linkForm">
<div class="mb-2">
<label class="form-label small">Source Node</label>
<select class="form-select form-select-sm" id="linkSource" required></select>
</div>
<div class="mb-2">
<label class="form-label small">Target Node</label>
<select class="form-select form-select-sm" id="linkTarget" required></select>
</div>
<div class="mb-2">
<label class="form-label small">Connection Type</label>
<select class="form-select form-select-sm" id="linkType">
<option value="direct">Direct</option>
<option value="vpn">VPN</option>
<option value="wireless">Wireless</option>
<option value="monitored">Monitored</option>
</select>
</div>
<div class="mb-2">
<label class="form-label small">Label</label>
<input type="text" class="form-control form-control-sm" id="linkLabel" placeholder="e.g. 1 Gbps, SSH Tunnel">
</div>
</form>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-primary" id="saveLink"><i class="fas fa-save me-1"></i> Add Link</button>
</div>
</div>
</div>
</div>
<!-- ==================== DOCUMENT MODAL ==================== -->
<div class="modal fade" id="documentModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-file-alt text-primary me-1"></i> <span id="documentModalLabel">New Document</span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="documentForm">
<div class="row mb-2">
<div class="col">
<label class="form-label small">Type</label>
<select class="form-select form-select-sm" id="docType" onchange="updateDocFormFields()">
<option value="deployment">Deployment</option>
<option value="attack">Attack</option>
<option value="incident-report">Incident Report</option>
<option value="remediation">Remediation</option>
<option value="exercise">Exercise</option>
</select>
</div>
<div class="col">
<label class="form-label small">Team</label>
<select class="form-select form-select-sm" id="docTeam" required></select>
</div>
</div>
<div class="mb-2">
<label class="form-label small">Title</label>
<input type="text" class="form-control form-control-sm" id="docTitle" required placeholder="e.g. Deploy new WAF, Phishing attack detected...">
</div>
<div class="mb-2" id="docFieldsContainer">
<div id="dynamicDocFields"></div>
</div>
<div class="mb-0">
<label class="form-label small">Notes / Additional Info</label>
<textarea class="form-control form-control-sm" id="docContent" rows="4" placeholder="Any additional details..."></textarea>
</div>
</form>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-primary" id="saveDocument"><i class="fas fa-save me-1"></i> Save Document</button>
</div>
</div>
</div>
</div>
<!-- ==================== LINK DOCS MODAL ==================== -->
<div class="modal fade" id="linkDocsModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-link text-info me-1"></i> Link Documents to Event</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="linkDocsList" class="mb-2"></div>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-info text-dark" id="saveLinkDocs"><i class="fas fa-link me-1"></i> Link Selected</button>
</div>
</div>
</div>
</div>
<!-- ==================== SETTINGS MODAL ==================== -->
<div class="modal fade" id="settingsModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title"><i class="fas fa-cog text-primary me-1"></i> Settings</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<h6 class="text-secondary mb-2"><i class="fas fa-users me-1"></i> Authorized Users</h6>
<div id="userList" class="mb-3">
<div class="text-secondary small">Loading...</div>
</div>
<hr class="border-secondary">
<h6 class="text-secondary mb-2"><i class="fas fa-user-plus me-1"></i> Add User by Token</h6>
<div class="input-group input-group-sm mb-2">
<input type="text" class="form-control" id="addUserToken" placeholder="Paste user token here">
<button class="btn btn-primary" id="addUserBtn"><i class="fas fa-plus"></i> Add</button>
</div>
<small class="text-secondary">Get the user token from the user's Jakach Auth profile or ask them to log in once.</small>
<hr class="border-secondary">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="text-secondary mb-0"><i class="fas fa-user-plus me-1"></i> New User Registration</h6>
<small class="text-secondary">Allow new users to register via login link</small>
</div>
<div class="form-check form-switch mb-0">
<input class="form-check-input" type="checkbox" id="registrationToggle" style="cursor:pointer;">
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ==================== CONFIRM MODAL ==================== -->
<div class="modal fade" id="confirmModal" tabindex="-1">
<div class="modal-dialog modal-sm modal-dialog-centered">
<div class="modal-content bg-dark">
<div class="modal-body text-center py-4">
<i class="fas fa-exclamation-triangle text-warning fs-3 mb-2"></i>
<p id="confirmMsg" class="mb-3">Are you sure?</p>
<div class="d-flex justify-content-center gap-2">
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-sm btn-danger" id="confirmBtn">Delete</button>
</div>
</div>
</div>
</div>
</div>
<!-- ==================== FILE VIEWER MODAL ==================== -->
<div class="modal fade" id="fileViewerModal" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary py-2">
<h6 class="modal-title" id="fileViewerTitle"><i class="fas fa-file me-1"></i> <span id="fileViewerName"></span></h6>
<div class="d-flex align-items-center gap-1">
<button type="button" class="btn btn-outline-primary btn-sm" id="fileViewerDownloadBtn"><i class="fas fa-download me-1"></i>Download</button>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
</div>
<div class="modal-body p-0" id="fileViewerBody" style="min-height:60vh;max-height:80vh;overflow:auto;background:#0d1117;">
<div class="text-center text-secondary py-5"><div class="spinner-border" role="status"></div><p class="mt-2 small">Loading file...</p></div>
</div>
</div>
</div>
</div>
<!-- ==================== LOGIN OVERLAY ==================== -->
<div id="loginOverlay" style="position:fixed;top:0;left:0;width:100%;height:100%;background:#0a0e1a;z-index:9999;display:flex;align-items:center;justify-content:center;">
<div style="text-align:center;max-width:400px;padding:2rem;">
<i class="fas fa-globe text-primary mb-3" style="font-size:2.5rem;"></i>
<h1 class="fw-bold mb-1">Neptune</h1>
<p class="text-secondary mb-4">Cybersecurity Incident Journal</p>
<div id="loginError" class="alert alert-danger py-2 small" style="display:none;"></div>
<div id="loginSuccess" class="alert alert-success py-2 small" style="display:none;"></div>
<button id="loginBtn" class="btn btn-primary w-100 py-2 mb-2">
<i class="fas fa-right-to-bracket me-2"></i>Log in with Jakach Auth
</button>
<small class="text-secondary">First user automatically becomes admin</small>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>