first commit

This commit is contained in:
Mateusz Gruszczyński
2026-02-13 12:42:53 +01:00
commit bc1b4279de
21 changed files with 3835 additions and 0 deletions

27
templates/404.html Normal file
View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 - Page Not Found | CVE Monitor</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row justify-content-center align-items-center" style="min-height: 100vh;">
<div class="col-md-6 text-center">
<i class="fas fa-exclamation-triangle text-warning" style="font-size: 5rem;"></i>
<h1 class="display-1 fw-bold mt-4">404</h1>
<h2 class="mb-4">Page Not Found</h2>
<p class="lead text-muted mb-4">
The page you are looking for doesn't exist or has been moved.
</p>
<a href="/" class="btn btn-primary btn-lg">
<i class="fas fa-home me-2"></i>Go Home
</a>
</div>
</div>
</div>
</body>
</html>

27
templates/500.html Normal file
View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>500 - Server Error | CVE Monitor</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row justify-content-center align-items-center" style="min-height: 100vh;">
<div class="col-md-6 text-center">
<i class="fas fa-server text-danger" style="font-size: 5rem;"></i>
<h1 class="display-1 fw-bold mt-4">500</h1>
<h2 class="mb-4">Internal Server Error</h2>
<p class="lead text-muted mb-4">
Something went wrong on our end. Please try again later.
</p>
<a href="/" class="btn btn-primary btn-lg">
<i class="fas fa-home me-2"></i>Go Home
</a>
</div>
</div>
</div>
</body>
</html>

89
templates/base.html Normal file
View File

@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="pl" data-bs-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{{ config.APP_NAME }}{% endblock %}</title>
<link href="{{ config.BOOTSTRAP_CSS_CDN }}" rel="stylesheet">
<link rel="stylesheet" href="{{ config.FONTAWESOME_CDN }}">
{% if config.ENABLE_CHARTS %}
<script src="{{ config.CHARTJS_CDN }}"></script>
{% endif %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
{% block extra_head %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<i class="fas fa-shield-alt me-2"></i>
<strong>{{ config.APP_NAME }}</strong>
</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="navbar-nav ms-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
<i class="fas fa-building me-1"></i> Vendors
</a>
<ul class="dropdown-menu dropdown-menu-end" id="vendorDropdown">
<li><div class="text-center py-2"><div class="spinner-border spinner-border-sm"></div></div></li>
</ul>
</li>
{% if config.ENABLE_DARK_MODE %}
<li class="nav-item">
<button class="btn btn-sm btn-outline-light ms-2" id="darkModeToggle" title="Toggle theme">
<i class="fas fa-moon"></i>
</button>
</li>
{% endif %}
<li class="nav-item">
<span class="navbar-text ms-3 small text-muted" id="lastUpdate">
<i class="fas fa-clock me-1"></i>Loading...
</span>
</li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid mt-4">
<div class="row">
<div class="col-md-3 col-lg-2 d-md-block sidebar">
<div class="position-sticky pt-3">
<h6 class="sidebar-heading px-3 mt-3 mb-2 text-muted text-uppercase">
<span>Vendors</span>
</h6>
<ul class="nav flex-column" id="vendorList">
<li class="nav-item">
<div class="text-center py-3">
<div class="spinner-border spinner-border-sm text-primary"></div>
</div>
</li>
</ul>
</div>
</div>
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
{% block content %}{% endblock %}
</main>
</div>
</div>
{% block modals %}{% endblock %}
<script src="{{ config.BOOTSTRAP_JS_CDN }}"></script>
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
{% block extra_scripts %}{% endblock %}
</body>
</html>

240
templates/index.html Normal file
View File

@@ -0,0 +1,240 @@
{% extends "base.html" %}
{% block title %}{{ config.APP_NAME }} - Dashboard{% endblock %}
{% block content %}
<!-- Header -->
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2" id="mainTitle">
<i class="fas fa-shield-alt text-primary me-2"></i>
CVE Dashboard
</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2">
<button type="button" class="btn btn-sm btn-outline-secondary" id="refreshBtn">
<i class="fas fa-sync-alt"></i> Refresh
</button>
{% if config.ENABLE_EXPORT %}
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown">
<i class="fas fa-download"></i> Export
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" id="exportJSON">Export JSON</a></li>
<li><a class="dropdown-item" href="#" id="exportCSV">Export CSV</a></li>
</ul>
{% endif %}
</div>
{% if config.ENABLE_SEARCH %}
<button type="button" class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#searchModal">
<i class="fas fa-search"></i> Search
</button>
{% endif %}
</div>
</div>
<!-- Stats Cards -->
<div class="row mb-4" id="statsCards">
<div class="col-md-3 col-sm-6 mb-3">
<div class="card border-primary">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-subtitle mb-2 text-muted">Total CVEs</h6>
<h3 class="card-title mb-0" id="statTotal">-</h3>
</div>
<div class="fs-1 text-primary"><i class="fas fa-bug"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-sm-6 mb-3">
<div class="card border-danger">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-subtitle mb-2 text-muted">Critical</h6>
<h3 class="card-title mb-0 text-danger" id="statCritical">-</h3>
</div>
<div class="fs-1 text-danger"><i class="fas fa-skull-crossbones"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-sm-6 mb-3">
<div class="card border-warning">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-subtitle mb-2 text-muted">High Risk</h6>
<h3 class="card-title mb-0 text-warning" id="statHigh">-</h3>
</div>
<div class="fs-1 text-warning"><i class="fas fa-exclamation-triangle"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-sm-6 mb-3">
<div class="card border-info">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-subtitle mb-2 text-muted">This Month</h6>
<h3 class="card-title mb-0 text-info" id="statMonth">-</h3>
</div>
<div class="fs-1 text-info"><i class="fas fa-calendar-alt"></i></div>
</div>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="card mb-3">
<div class="card-body">
<form class="row g-3" id="filterForm">
<div class="col-md-4">
<label class="form-label">Severity</label>
<select class="form-select" id="filterSeverity">
<option value="">All Severities</option>
<option value="CRITICAL">Critical</option>
<option value="HIGH">High</option>
<option value="MEDIUM">Medium</option>
<option value="LOW">Low</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Year</label>
<select class="form-select" id="filterYear">
<option value="">All Years</option>
<option value="2026">2026</option>
<option value="2025">2025</option>
<option value="2024">2024</option>
</select>
</div>
<div class="col-md-4 d-flex align-items-end">
<button type="submit" class="btn btn-primary me-2">
<i class="fas fa-filter"></i> Apply
</button>
<button type="button" class="btn btn-secondary" id="clearFilters">
<i class="fas fa-times"></i> Clear
</button>
</div>
</form>
</div>
</div>
<!-- CVE Table -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0"><i class="fas fa-list me-2"></i>Vulnerabilities</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover" id="cveTable">
<thead>
<tr>
<th>CVE ID</th>
<th>Severity</th>
<th>CVSS</th>
<th>Description</th>
<th>Published</th>
</tr>
</thead>
<tbody id="cveTableBody">
<tr>
<td colspan="5" class="text-center py-4">
<div class="spinner-border text-primary" role="status"></div>
<p class="mt-2 text-muted">Loading CVE data...</p>
</td>
</tr>
</tbody>
</table>
</div>
<nav id="paginationNav" class="d-none">
<ul class="pagination justify-content-center mb-0">
<li class="page-item disabled" id="prevPage">
<a class="page-link" href="#"><i class="fas fa-chevron-left"></i></a>
</li>
<li class="page-item active">
<span class="page-link" id="currentPage">1</span>
</li>
<li class="page-item" id="nextPage">
<a class="page-link" href="#"><i class="fas fa-chevron-right"></i></a>
</li>
</ul>
</nav>
</div>
</div>
{% if config.ENABLE_CHARTS %}
<!-- Charts -->
<div class="row mb-4">
<div class="col-lg-8 mb-3">
<div class="card">
<div class="card-header">
<h5 class="mb-0"><i class="fas fa-chart-bar me-2"></i>CVE Trend (Last 12 Months)</h5>
</div>
<div class="card-body">
<canvas id="trendChart" height="80"></canvas>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card">
<div class="card-header">
<h5 class="mb-0"><i class="fas fa-chart-pie me-2"></i>Severity Distribution</h5>
</div>
<div class="card-body">
<canvas id="severityChart"></canvas>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block modals %}
<!-- CVE Detail Modal -->
<div class="modal fade" id="cveModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="cveModalTitle">CVE Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="cveModalBody"></div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% if config.ENABLE_SEARCH %}
<!-- Search Modal -->
<div class="modal fade" id="searchModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Search CVEs</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<input type="text" class="form-control" id="searchInput" placeholder="Search by CVE ID or keyword...">
<button class="btn btn-primary" id="searchBtn">
<i class="fas fa-search"></i> Search
</button>
</div>
<div id="searchResults"></div>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}