1. Source drop box: token-gated anonymous upload with auto-attestation, EXIF stripping, receipt codes, and self-destructing URLs. New /dropbox blueprint with admin panel for token management. CSRF exempted for source-facing upload routes. 2. Investigation namespaces: attestation records tagged with investigation label via metadata. Log view filters by investigation with dropdown. Supports long-running multi-story workflows. 3. Scale fixes: replaced O(n) full-scan perceptual hash search with LMDB find_similar_images() index lookup. Added incremental chain verification (verify_incremental) with last_verified_index checkpoint in ChainState. 4. Deep forensic purge: killswitch now scrubs __pycache__, pip dist-info, pip cache, and shell history entries containing 'soosef'. Runs before package uninstall for maximum trace removal. 5. Cross-org federation: new federation/exchange.py with export_attestation_bundle() and import_attestation_bundle(). Bundles are self-authenticating JSON with investigation filter. Import validates against trust store fingerprints. 6. Wrong-key diagnostics: enhanced decrypt error messages include current channel key fingerprint hint. New carrier_tracker.py tracks carrier SHA-256 hashes and warns on reuse (statistical analysis risk). 7. Selective disclosure: ChainStore.selective_disclosure() produces proof bundles with full selected records + hash-only redacted records + complete hash chain for linkage verification. New `soosef chain disclose -i 0,5,10 -o proof.json` CLI command for court-ordered evidence production. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
72 lines
2.7 KiB
HTML
72 lines
2.7 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Source Drop Box — SooSeF{% endblock %}
|
|
{% block content %}
|
|
<h2><i class="bi bi-inbox me-2"></i>Source Drop Box</h2>
|
|
<p class="text-muted">Create time-limited upload links for sources who cannot install SooSeF.</p>
|
|
|
|
<div class="card bg-dark mb-4">
|
|
<div class="card-body">
|
|
<h5 class="card-title">Create Upload Token</h5>
|
|
<form method="POST">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
|
<input type="hidden" name="action" value="create">
|
|
<div class="row g-3">
|
|
<div class="col-md-4">
|
|
<label class="form-label">Label (internal only)</label>
|
|
<input type="text" name="label" class="form-control bg-dark text-light"
|
|
placeholder="e.g., Gulf Ministry Source">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Expires in (hours)</label>
|
|
<input type="number" name="hours" value="24" min="1" max="168"
|
|
class="form-control bg-dark text-light">
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Max files</label>
|
|
<input type="number" name="max_files" value="10" min="1" max="100"
|
|
class="form-control bg-dark text-light">
|
|
</div>
|
|
<div class="col-md-2 d-flex align-items-end">
|
|
<button type="submit" class="btn btn-primary w-100">Create</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{% if tokens %}
|
|
<h5>Active Tokens</h5>
|
|
<table class="table table-dark table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th>Label</th>
|
|
<th>Token</th>
|
|
<th>Used / Max</th>
|
|
<th>Expires</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for token, data in tokens.items() %}
|
|
<tr>
|
|
<td>{{ data.label }}</td>
|
|
<td><code>{{ token[:12] }}...</code></td>
|
|
<td>{{ data.used }} / {{ data.max_files }}</td>
|
|
<td>{{ data.expires_at[:16] }}</td>
|
|
<td>
|
|
<form method="POST" class="d-inline">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
|
<input type="hidden" name="action" value="revoke">
|
|
<input type="hidden" name="token" value="{{ token }}">
|
|
<button type="submit" class="btn btn-sm btn-outline-danger">Revoke</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}
|
|
<p class="text-muted">No active upload tokens.</p>
|
|
{% endif %}
|
|
{% endblock %}
|