fieldwitness/frontends/web/templates/base.html
Aaron D. Lee 490f9d4a1d Rebrand SooSeF to FieldWitness
Complete project rebrand for better positioning in the press freedom
and digital security space. FieldWitness communicates both field
deployment and evidence testimony — appropriate for the target audience
of journalists, NGOs, and human rights organizations.

Rename mapping:
- soosef → fieldwitness (package, CLI, all imports)
- soosef.stegasoo → fieldwitness.stego
- soosef.verisoo → fieldwitness.attest
- ~/.soosef/ → ~/.fwmetadata/ (innocuous data dir name)
- SOOSEF_DATA_DIR → FIELDWITNESS_DATA_DIR
- SoosefConfig → FieldWitnessConfig
- SoosefError → FieldWitnessError

Also includes:
- License switch from MIT to GPL-3.0
- C2PA bridge module (Phase 0-2 MVP): cert.py, export.py, vendor_assertions.py
- README repositioned to lead with provenance/federation, stego backgrounded
- Threat model skeleton at docs/security/threat-model.md
- Planning docs: docs/planning/c2pa-integration.md, docs/planning/gtm-feasibility.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:05:13 -04:00

157 lines
8.6 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>{% block title %}FieldWitness{% endblock %}</title>
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
<link href="{{ url_for('static', filename='vendor/css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='vendor/css/bootstrap-icons.min.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="/" style="padding-left: 6px; margin-right: 8px;">
<strong>FieldWitness</strong>
</a>
{# Channel + Identity indicators #}
<span class="d-flex align-items-center me-auto gap-2">
{% if channel_configured %}
<span class="badge bg-success bg-opacity-25 small" title="Channel: {{ channel_fingerprint }}">
<i class="bi bi-shield-lock me-1" style="color: #6ee7b7;"></i><code style="font-size: 0.7rem; font-weight: 300; color: #c9a860;">{{ channel_fingerprint[:4] }}-{{ channel_fingerprint[-4:] }}</code>
</span>
{% endif %}
{% if identity_configured %}
<span class="badge bg-info bg-opacity-25 small" title="Identity: {{ identity_fingerprint }}">
<i class="bi bi-fingerprint me-1"></i><code style="font-size: 0.7rem; font-weight: 300;">{{ identity_fingerprint[:8] }}</code>
</span>
{% endif %}
</span>
<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 nav-icons">
<li class="nav-item">
<a class="nav-link nav-expand" href="/"><i class="bi bi-house"></i><span>Home</span></a>
</li>
{% if not auth_enabled or is_authenticated %}
{# ── Stego ── #}
<li class="nav-item">
<a class="nav-link nav-expand" href="/encode"><i class="bi bi-lock"></i><span>Encode</span></a>
</li>
<li class="nav-item">
<a class="nav-link nav-expand" href="/decode"><i class="bi bi-unlock"></i><span>Decode</span></a>
</li>
<li class="nav-item">
<a class="nav-link nav-expand" href="/generate"><i class="bi bi-key"></i><span>Generate</span></a>
</li>
{# ── Attest ── #}
{% if has_attest %}
<li class="nav-item">
<a class="nav-link nav-expand" href="/attest"><i class="bi bi-patch-check"></i><span>Attest</span></a>
</li>
<li class="nav-item">
<a class="nav-link nav-expand" href="/verify"><i class="bi bi-search"></i><span>Verify</span></a>
</li>
{% endif %}
{# ── Fieldkit ── #}
{% if has_fieldkit %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
<i class="bi bi-shield-exclamation me-1"></i>
Fieldkit
{% if fieldkit_status == 'alarm' %}
<span class="badge bg-danger rounded-pill ms-1">!</span>
{% elif fieldkit_status == 'warn' %}
<span class="badge bg-warning rounded-pill ms-1">!</span>
{% endif %}
</a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-dark">
<li><a class="dropdown-item" href="/fieldkit"><i class="bi bi-speedometer2 me-2"></i>Status</a></li>
<li><a class="dropdown-item" href="/fieldkit/killswitch"><i class="bi bi-exclamation-octagon me-2"></i>Killswitch</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/keys"><i class="bi bi-key me-2"></i>Keys</a></li>
</ul>
</li>
{% endif %}
{% endif %}
<li class="nav-item">
<a class="nav-link nav-expand" href="/tools"><i class="bi bi-tools"></i><span>Tools</span></a>
</li>
{# ── User menu ── #}
{% if auth_enabled %}
{% if is_authenticated %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
<i class="bi bi-person-circle me-1"></i> {{ username }}
</a>
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-dark">
<li><a class="dropdown-item" href="/account"><i class="bi bi-gear me-2"></i>Account</a></li>
{% if is_admin %}
<li><a class="dropdown-item" href="/admin/users"><i class="bi bi-people me-2"></i>Users</a></li>
<li><a class="dropdown-item" href="/admin/settings"><i class="bi bi-sliders me-2"></i>Settings</a></li>
{% endif %}
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/keys"><i class="bi bi-key me-2"></i>Keys</a></li>
<li><form method="POST" action="/logout" class="d-inline"><input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/><button type="submit" class="dropdown-item"><i class="bi bi-box-arrow-left me-2"></i>Logout</button></form></li>
</ul>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="/login"><i class="bi bi-box-arrow-in-right me-1"></i> Login</a>
</li>
{% endif %}
{% endif %}
</ul>
</div>
</div>
</nav>
<main class="container py-5">
{# Toast notifications #}
<div class="toast-container position-fixed end-0 p-3" style="z-index: 1100; top: 70px;">
{% with messages = get_flashed_messages(with_categories=true) %}
{% for category, message in messages %}
<div class="toast show align-items-center text-bg-{{ 'danger' if category == 'error' else ('warning' if category == 'warning' else 'success') }} border-0 fade" role="alert" data-bs-autohide="true" data-bs-delay="10000">
<div class="d-flex">
<div class="toast-body">
<i class="bi bi-{{ 'exclamation-triangle' if category == 'error' else ('exclamation-circle' if category == 'warning' else 'check-circle') }} me-2"></i>
{{ message }}
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
</div>
</div>
{% endfor %}
{% endwith %}
</div>
{% block content %}{% endblock %}
</main>
<footer class="py-4 mt-5">
<div class="container text-center text-muted">
<small>
FieldWitness v{{ version }} — FieldWitness
<span class="mx-2">|</span>
<span class="text-muted">Stego + Attest</span>
</small>
</div>
</footer>
<script src="{{ url_for('static', filename='vendor/js/bootstrap.bundle.min.js') }}"></script>
<script>
document.querySelectorAll('.toast').forEach(el => new bootstrap.Toast(el));
</script>
{% block scripts %}{% endblock %}
</body>
</html>