Promote develop → main (2026-05-22 19:10 UTC) #45
@@ -1,4 +1,12 @@
|
||||
[
|
||||
{
|
||||
"version": "2026-05-22T19:10Z",
|
||||
"date": "2026-05-22",
|
||||
"title": "Exportdialog: Ersteller manuell eintragbar",
|
||||
"items": [
|
||||
"Im Export-Dialog kann der Ersteller jetzt manuell eingegeben werden."
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2026-05-22T07:41Z",
|
||||
"date": "2026-05-22",
|
||||
|
||||
@@ -1153,6 +1153,7 @@ async def export_incident(
|
||||
scope: str = Query("report", pattern="^(summary|report|full)$"),
|
||||
sections: str = Query(None),
|
||||
branding: str = Query("on", pattern="^(on|off)$"),
|
||||
creator: str = Query(None, max_length=120),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
db: aiosqlite.Connection = Depends(db_dependency),
|
||||
):
|
||||
@@ -1171,10 +1172,13 @@ async def export_incident(
|
||||
row = await _check_incident_access(db, incident_id, current_user["id"], tenant_id)
|
||||
incident = dict(row)
|
||||
|
||||
# Ersteller-Name
|
||||
cursor = await db.execute("SELECT email FROM users WHERE id = ?", (incident["created_by"],))
|
||||
user_row = await cursor.fetchone()
|
||||
creator = user_row["email"] if user_row else "Unbekannt"
|
||||
# Ersteller-Name: manuell uebergebener Wert hat Vorrang, sonst E-Mail des Lage-Erstellers
|
||||
if creator and creator.strip():
|
||||
creator = creator.strip()
|
||||
else:
|
||||
cursor = await db.execute("SELECT email FROM users WHERE id = ?", (incident["created_by"],))
|
||||
user_row = await cursor.fetchone()
|
||||
creator = user_row["email"] if user_row else "Unbekannt"
|
||||
|
||||
# Organisation (fuer Dateimetadaten)
|
||||
organization_name = None
|
||||
|
||||
@@ -805,12 +805,12 @@
|
||||
<script src="/static/vendor/leaflet.js"></script>
|
||||
<script src="/static/vendor/leaflet.markercluster.js"></script>
|
||||
<script src="/static/js/i18n.js?v=20260513a"></script>
|
||||
<script src="/static/js/api.js?v=20260522e"></script>
|
||||
<script src="/static/js/api.js?v=20260522f"></script>
|
||||
<script src="/static/js/ws.js?v=20260316b"></script>
|
||||
<script src="/static/js/components.js?v=20260522d"></script>
|
||||
<script src="/static/js/layout.js?v=20260513f"></script>
|
||||
<script src="/static/js/pipeline.js?v=20260513d"></script>
|
||||
<script src="/static/js/app.js?v=20260522e"></script>
|
||||
<script src="/static/js/app.js?v=20260522f"></script>
|
||||
<script src="/static/js/cluster-data.js?v=20260322f"></script>
|
||||
<script src="/static/js/tutorial.js?v=20260316z"></script>
|
||||
<script src="/static/js/chat.js?v=20260514e"></script>
|
||||
@@ -855,6 +855,11 @@
|
||||
<label class="export-radio"><input type="radio" name="export-branding" value="on" checked><span data-i18n="export.branding.on">Mit AegisSight-Branding</span></label>
|
||||
<label class="export-radio"><input type="radio" name="export-branding" value="off"><span data-i18n="export.branding.off">Ohne Firmen-Branding</span></label>
|
||||
</div>
|
||||
<div style="margin-bottom:0;">
|
||||
<label for="export-ersteller" style="font-size:11px;text-transform:uppercase;letter-spacing:1px;color:var(--text-secondary);display:block;margin-bottom:8px;">Ersteller</label>
|
||||
<input type="text" id="export-ersteller" maxlength="120" placeholder="Name des Erstellers (optional)" style="width:100%;box-sizing:border-box;">
|
||||
<div style="font-size:11px;color:var(--text-secondary);margin-top:6px;">Leer lassen, dann wird automatisch der Lage-Ersteller verwendet.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="padding:12px 20px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid var(--border);">
|
||||
<button class="btn btn-secondary" onclick="closeModal('modal-export')" data-i18n="common.cancel">Abbrechen</button>
|
||||
|
||||
@@ -330,7 +330,7 @@ const API = {
|
||||
resetTutorialState() {
|
||||
return this._request('DELETE', '/tutorial/state');
|
||||
},
|
||||
exportReport(id, format, scope, sections, includeBranding) {
|
||||
exportReport(id, format, scope, sections, includeBranding, creator) {
|
||||
const token = localStorage.getItem('osint_token');
|
||||
let url = `${this.baseUrl}/incidents/${id}/export?format=${format}`;
|
||||
if (sections && sections.length > 0) {
|
||||
@@ -341,6 +341,9 @@ const API = {
|
||||
if (includeBranding === false) {
|
||||
url += `&branding=off`;
|
||||
}
|
||||
if (creator) {
|
||||
url += `&creator=${encodeURIComponent(creator)}`;
|
||||
}
|
||||
return fetch(url, {
|
||||
headers: { 'Authorization': `Bearer ${token}` },
|
||||
});
|
||||
|
||||
@@ -2639,6 +2639,7 @@ async handleRefresh() {
|
||||
const format = document.querySelector('input[name="export-format"]:checked').value;
|
||||
const brandingEl = document.querySelector('input[name="export-branding"]:checked');
|
||||
const includeBranding = !brandingEl || brandingEl.value === 'on';
|
||||
const ersteller = (document.getElementById('export-ersteller')?.value || '').trim();
|
||||
|
||||
const btn = document.getElementById('export-submit-btn');
|
||||
const origText = btn.textContent;
|
||||
@@ -2646,7 +2647,7 @@ async handleRefresh() {
|
||||
btn.textContent = (typeof T === 'function' ? T('action.creating', 'Wird erstellt...') : 'Wird erstellt...');
|
||||
|
||||
try {
|
||||
const response = await API.exportReport(this.currentIncidentId, format, null, sections, includeBranding);
|
||||
const response = await API.exportReport(this.currentIncidentId, format, null, sections, includeBranding, ersteller);
|
||||
if (!response.ok) {
|
||||
const err = await response.json().catch(() => ({}));
|
||||
throw new Error(err.detail || 'Fehler ' + response.status);
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren