Cleanup: Backup-Dateien (.bak) entfernt
Dieser Commit ist enthalten in:
@@ -1,237 +0,0 @@
|
||||
/**
|
||||
* API-Client für den OSINT Lagemonitor.
|
||||
*/
|
||||
const API = {
|
||||
baseUrl: '/api',
|
||||
|
||||
_getHeaders() {
|
||||
const token = localStorage.getItem('osint_token');
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': token ? `Bearer ${token}` : '',
|
||||
};
|
||||
},
|
||||
|
||||
async _request(method, path, body = null) {
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 30000);
|
||||
|
||||
const options = {
|
||||
method,
|
||||
headers: this._getHeaders(),
|
||||
signal: controller.signal,
|
||||
};
|
||||
if (body) {
|
||||
options.body = JSON.stringify(body);
|
||||
}
|
||||
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(`${this.baseUrl}${path}`, options);
|
||||
} catch (err) {
|
||||
clearTimeout(timeout);
|
||||
if (err.name === 'AbortError') {
|
||||
throw new Error('Zeitüberschreitung bei der Anfrage');
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (response.status === 401) {
|
||||
localStorage.removeItem('osint_token');
|
||||
localStorage.removeItem('osint_username');
|
||||
window.location.href = '/';
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
let detail = data.detail;
|
||||
if (Array.isArray(detail)) {
|
||||
detail = detail.map(e => e.msg || JSON.stringify(e)).join('; ');
|
||||
} else if (typeof detail === 'object' && detail !== null) {
|
||||
detail = JSON.stringify(detail);
|
||||
}
|
||||
throw new Error(detail || `Fehler ${response.status}`);
|
||||
}
|
||||
|
||||
if (response.status === 204) return null;
|
||||
return response.json();
|
||||
},
|
||||
|
||||
// Auth
|
||||
getMe() {
|
||||
return this._request('GET', '/auth/me');
|
||||
},
|
||||
|
||||
// Incidents
|
||||
listIncidents(statusFilter = null) {
|
||||
const query = statusFilter ? `?status_filter=${statusFilter}` : '';
|
||||
return this._request('GET', `/incidents${query}`);
|
||||
},
|
||||
|
||||
createIncident(data) {
|
||||
return this._request('POST', '/incidents', data);
|
||||
},
|
||||
|
||||
getRefreshingIncidents() {
|
||||
return this._request('GET', '/incidents/refreshing');
|
||||
},
|
||||
|
||||
getIncident(id) {
|
||||
return this._request('GET', `/incidents/${id}`);
|
||||
},
|
||||
|
||||
updateIncident(id, data) {
|
||||
return this._request('PUT', `/incidents/${id}`, data);
|
||||
},
|
||||
|
||||
deleteIncident(id) {
|
||||
return this._request('DELETE', `/incidents/${id}`);
|
||||
},
|
||||
|
||||
getArticles(incidentId) {
|
||||
return this._request('GET', `/incidents/${incidentId}/articles`);
|
||||
},
|
||||
|
||||
getFactChecks(incidentId) {
|
||||
return this._request('GET', `/incidents/${incidentId}/factchecks`);
|
||||
},
|
||||
|
||||
getSnapshots(incidentId) {
|
||||
return this._request('GET', `/incidents/${incidentId}/snapshots`);
|
||||
},
|
||||
|
||||
getLocations(incidentId) {
|
||||
return this._request('GET', `/incidents/${incidentId}/locations`);
|
||||
},
|
||||
|
||||
triggerGeoparse(incidentId) {
|
||||
return this._request('POST', `/incidents/${incidentId}/geoparse`);
|
||||
},
|
||||
|
||||
getGeoparseStatus(incidentId) {
|
||||
return this._request('GET', `/incidents/${incidentId}/geoparse-status`);
|
||||
},
|
||||
|
||||
refreshIncident(id) {
|
||||
return this._request('POST', `/incidents/${id}/refresh`);
|
||||
},
|
||||
|
||||
getRefreshLog(incidentId, limit = 20) {
|
||||
return this._request('GET', `/incidents/${incidentId}/refresh-log?limit=${limit}`);
|
||||
},
|
||||
|
||||
// Sources (Quellenverwaltung)
|
||||
listSources(params = {}) {
|
||||
const query = new URLSearchParams();
|
||||
if (params.source_type) query.set('source_type', params.source_type);
|
||||
if (params.category) query.set('category', params.category);
|
||||
if (params.source_status) query.set('source_status', params.source_status);
|
||||
const qs = query.toString();
|
||||
return this._request('GET', `/sources${qs ? '?' + qs : ''}`);
|
||||
},
|
||||
|
||||
createSource(data) {
|
||||
return this._request('POST', '/sources', data);
|
||||
},
|
||||
|
||||
updateSource(id, data) {
|
||||
return this._request('PUT', `/sources/${id}`, data);
|
||||
},
|
||||
|
||||
deleteSource(id) {
|
||||
return this._request('DELETE', `/sources/${id}`);
|
||||
},
|
||||
|
||||
getSourceStats() {
|
||||
return this._request('GET', '/sources/stats');
|
||||
},
|
||||
|
||||
discoverMulti(url) {
|
||||
return this._request('POST', '/sources/discover-multi', { url });
|
||||
},
|
||||
|
||||
getMyExclusions() {
|
||||
return this._request('GET', '/sources/my-exclusions');
|
||||
},
|
||||
|
||||
blockDomain(domain, notes) {
|
||||
return this._request('POST', '/sources/block-domain', { domain, notes });
|
||||
},
|
||||
|
||||
unblockDomain(domain) {
|
||||
return this._request('POST', '/sources/unblock-domain', { domain });
|
||||
},
|
||||
|
||||
deleteDomain(domain) {
|
||||
return this._request('DELETE', `/sources/domain/${encodeURIComponent(domain)}`);
|
||||
},
|
||||
|
||||
cancelRefresh(id) {
|
||||
return this._request('POST', `/incidents/${id}/cancel-refresh`);
|
||||
},
|
||||
|
||||
// Notifications
|
||||
listNotifications(limit = 50) {
|
||||
return this._request('GET', `/notifications?limit=${limit}`);
|
||||
},
|
||||
|
||||
markNotificationsRead(ids = null) {
|
||||
return this._request('PUT', '/notifications/mark-read', { notification_ids: ids });
|
||||
},
|
||||
|
||||
|
||||
|
||||
// Subscriptions (E-Mail-Benachrichtigungen)
|
||||
getSubscription(incidentId) {
|
||||
return this._request('GET', '/incidents/' + incidentId + '/subscription');
|
||||
},
|
||||
|
||||
updateSubscription(incidentId, data) {
|
||||
return this._request('PUT', '/incidents/' + incidentId + '/subscription', data);
|
||||
},
|
||||
|
||||
// Feedback
|
||||
sendFeedback(data) {
|
||||
return this._request('POST', '/feedback', data);
|
||||
},
|
||||
|
||||
async sendFeedbackForm(formData) {
|
||||
const token = localStorage.getItem('osint_token');
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 60000);
|
||||
const resp = await fetch(this.baseUrl + '/feedback', {
|
||||
method: 'POST',
|
||||
headers: { 'Authorization': token ? 'Bearer ' + token : '' },
|
||||
body: formData,
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeout);
|
||||
if (!resp.ok) {
|
||||
const err = await resp.json().catch(() => ({}));
|
||||
throw new Error(err.detail || 'Fehler ' + resp.status);
|
||||
}
|
||||
},
|
||||
|
||||
// Export
|
||||
|
||||
// Tutorial-Fortschritt
|
||||
getTutorialState() {
|
||||
return this._request('GET', '/tutorial/state');
|
||||
},
|
||||
|
||||
saveTutorialState(data) {
|
||||
return this._request('PUT', '/tutorial/state', data);
|
||||
},
|
||||
|
||||
resetTutorialState() {
|
||||
return this._request('DELETE', '/tutorial/state');
|
||||
},
|
||||
exportReport(id, format, scope, classification) {
|
||||
const token = localStorage.getItem('osint_token');
|
||||
return fetch(`${this.baseUrl}/incidents/${id}/export?format=${format}&scope=${scope}&classification=${classification}`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` },
|
||||
});
|
||||
},
|
||||
};
|
||||
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
In neuem Issue referenzieren
Einen Benutzer sperren