This commit is contained in:
m3tam3re
2026-07-16 15:05:58 +02:00
commit 514ee9a2e3
38 changed files with 9020 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
export async function GET() {
try {
const baserowToken = process.env.BASEROW_API_TOKEN?.trim();
const baserowTableUrl = process.env.BASEROW_TABLE_URL?.trim();
const campaignsUrl = process.env.BASEROW_CAMPAIGNS_TABLE_URL?.trim();
if (baserowToken) {
let apiUrl = '';
if (campaignsUrl && campaignsUrl.includes('/database/')) {
const match = campaignsUrl.match(/\/table\/(\d+)/);
if (match) {
const tableId = match[1];
const baseUrl = new URL(campaignsUrl).origin;
apiUrl = `${baseUrl}/api/database/rows/table/${tableId}/?user_field_names=true&size=200`;
}
} else if (baserowTableUrl && baserowTableUrl.includes('/database/')) {
const baseUrl = new URL(baserowTableUrl).origin;
// Fallback: Table 1103 is "Simulationen"
apiUrl = `${baseUrl}/api/database/rows/table/1103/?user_field_names=true&size=200`;
}
if (!apiUrl) {
return NextResponse.json([]);
}
let allResults: any[] = [];
let nextUrl: string | null = apiUrl;
while (nextUrl) {
nextUrl = nextUrl.replace(/^http:\/\//i, 'https://');
const response: Response = await fetch(nextUrl, {
headers: {
Authorization: `Token ${baserowToken}`,
},
});
if (!response.ok) {
throw new Error('Fehler beim Abrufen der Baserow-Daten (Campaigns): ' + response.status);
}
const data: any = await response.json();
if (data.results) {
allResults = allResults.concat(data.results);
}
nextUrl = data.next;
}
const transformedData = allResults.map((row: any) => ({
Simulation: row['Simulation'] || '',
Quelle: row['Quelle']?.value || '',
Simulationsname: row['Simulationsname']?.value || '',
Simulationstyp: row['Simulationstyp']?.value || '',
Vorschau: row['Vorschau'] || [],
Absendername: row['Absendername'] || '',
Von: row['Von'] || '',
Betreff: row['Betreff'] || '',
'Phishing-Link/Anlage': row['Phishing-Link/Anlage'] || ''
}));
return NextResponse.json(transformedData);
}
return NextResponse.json([]);
} catch (error: any) {
console.error('API Error (Campaigns):', error);
return NextResponse.json({ error: error.message || 'Interner Serverfehler' }, { status: 500 });
}
}
+20
View File
@@ -0,0 +1,20 @@
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const body = await request.json();
if (body.password === process.env.DASHBOARD_PASSWORD) {
const response = NextResponse.json({ success: true });
// Set cookie for 1 day
response.cookies.set({
name: 'auth_session',
value: 'authenticated',
httpOnly: true,
path: '/',
maxAge: 60 * 60 * 24,
});
return response;
}
return NextResponse.json({ success: false }, { status: 401 });
}
+76
View File
@@ -0,0 +1,76 @@
import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
// Das ist die Schnittstelle, die Live-Daten von Baserow holt.
export async function GET() {
try {
const baserowToken = process.env.BASEROW_API_TOKEN?.trim();
const baserowTableUrl = (process.env.BASEROW_PHISHING_TABLE_URL || process.env.BASEROW_TABLE_URL)?.trim();
// 1. Wenn Baserow-Zugangsdaten vorhanden sind, Live-Daten abrufen:
if (baserowToken && baserowTableUrl) {
let apiUrl = baserowTableUrl;
// Konvertiere UI URL (z.B. https://br.az-gruppe.com/database/423/table/1091/4099) in API URL
if (baserowTableUrl.includes('/database/')) {
const match = baserowTableUrl.match(/\/table\/(\d+)/);
if (match) {
const tableId = match[1];
const baseUrl = new URL(baserowTableUrl).origin;
apiUrl = `${baseUrl}/api/database/rows/table/${tableId}/?user_field_names=true&size=200`;
}
}
let allResults: any[] = [];
let nextUrl: string | null = apiUrl;
while (nextUrl) {
// Fix: Falls Baserow HTTP statt HTTPS für next_url zurückgibt (z.B. wegen Reverse Proxy),
// zwingen wir es auf HTTPS, damit fetch den Authorization-Header beim Redirect nicht droppt!
nextUrl = nextUrl.replace(/^http:\/\//i, 'https://');
const response: Response = await fetch(nextUrl, {
headers: {
Authorization: `Token ${baserowToken}`,
},
});
if (!response.ok) {
const errText = await response.text();
throw new Error('Fehler beim Abrufen der Baserow-Daten: ' + response.status + ' ' + errText);
}
const data: any = await response.json();
if (data.results) {
allResults = allResults.concat(data.results);
}
nextUrl = data.next; // Pagination von Baserow
}
// Transformiere Baserow-Daten in das Format, das das Dashboard erwartet (wie CSV)
const transformedData = allResults.map((row: any) => ({
Simulationstyp: row.Simulationstyp?.[0]?.value?.value || '',
Name: row.Name?.value || row.Name || '',
NameColor: row.Name?.color || '',
Gelesen: row.Gelesen ? 'True' : 'False',
'Link Geklickt': row['Link Geklickt']?.value || row['Link Geklickt'] || '',
'Anmeldeinfos eingegeben': row['Anmeldeinfos eingegeben']?.value || row['Anmeldeinfos eingegeben'] || '',
'IT Kontakt': row['IT Kontakt']?.value || row['IT Kontakt'] || '',
'Gelöscht': row['Gelöscht'] ? 'True' : 'False',
'Weitergeleitet': row['Weitergeleitet'] ? 'True' : 'False',
'Anlage geöffnet': row['Anlage geöffnet']?.value || row['Anlage geöffnet'] || '',
'Gesendet': row['Gesendet'] || '',
'Abgeschlossen': row['Abgeschlossen'] || '',
'Simulation': row['Simulation']?.[0]?.value || '',
}));
return NextResponse.json(transformedData);
}
return NextResponse.json([]);
} catch (error: any) {
console.error('API Error:', error);
return NextResponse.json({ error: error.message || 'Interner Serverfehler' }, { status: 500 });
}
}