- A-01/A-02/A-04: archive_pending_jobs je Vorgang (ArchivePendingQueue), Depublikationsstand am Auftrag festgehalten, Nachholer ohne Schlüssel FAILURE; archive_pending_at nur noch Sammelmarker - O07: Direktweg und Nachholer beanspruchen den Auftrag unter Zeilensperre - O08: fehlende Snapshot-Datei → Verweis auf den image_removed-Eintrag oder offener Auftrag, nie ein still unvollständiger Nachweis - A-03/A-06: Sweep verschiebt in die Quarantäne, Pause beim Restore, archive:reregister; Restore-Abgleich löscht Anwendungskopien erneut - O04/O05: Restore ordnet über den Payload-Pfad zu; unsignierte Exporte nur mit --accept-unsigned, reregister bricht bei ungültigem/fehlendem Export ab - A-05, A-07 bis A-15: Altbestand als möglicherweise veröffentlicht, Hold- Historie, Zweck per POST, Nachweise gelöschter Bilder nur mit compliance:manage, Anhänge auf ihrer Disk, Schlüssel-ID und ARCHIVE_PREVIOUS_KEYS, HMAC per HKDF, archive:verify-export - 5.1 d: Depublikation im Meldeverfahren trägt legal_request_id PressReleaseService.php enthält zusätzlich K-01 (Prüfung im Publish-Lock), N19 (archive() gibt Kopien frei) und N09 (markImagesPublished nur für auslieferbare Bilder), weil die Datei ungeteilt committet ist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.6 KiB
PHP
62 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Services\Archive\EvidenceArchive;
|
|
use Illuminate\Console\Command;
|
|
|
|
/**
|
|
* Beweisarchiv (Umsetzungsaudit 29.09.2026, A-03): nach einem DB-Restore
|
|
* die Zeilen für Payloads ohne Zeile aus deren manifest.json wieder
|
|
* anlegen — aus `entries/` und aus der Quarantäne. Laut Tombstone-Export
|
|
* gelöschte Payloads bleiben außen vor. Legal Hold kennt das Manifest
|
|
* nicht: wiederhergestellte Einträge im Admin prüfen.
|
|
*/
|
|
class ArchiveReregister extends Command
|
|
{
|
|
protected $signature = 'archive:reregister
|
|
{--dry-run : Nur zählen}
|
|
{--accept-unsigned : Unsignierten Tombstone-Export verwenden (nur Exporte vor dem 29.09.2026)}
|
|
{--without-export : Ohne Tombstone-Export registrieren (gelöschte Einträge können zurückkehren)}';
|
|
|
|
protected $description = 'Registriert Beweisarchiv-Payloads ohne Zeile anhand ihres Manifests neu (nach DB-Restore)';
|
|
|
|
public function handle(EvidenceArchive $archive): int
|
|
{
|
|
if (! $archive->isConfigured()) {
|
|
$this->error('ARCHIVE_KEY fehlt oder ist ungültig — Payloads lassen sich nicht lesen.');
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$result = $archive->reregister(
|
|
(bool) $this->option('dry-run'),
|
|
(bool) $this->option('accept-unsigned'),
|
|
(bool) $this->option('without-export'),
|
|
);
|
|
|
|
if ($result['aborted']) {
|
|
$this->error(match ($result['export_signature']) {
|
|
'invalid' => 'Tombstone-Export mit ungültiger Signatur — abgebrochen, nichts registriert. Ist ARCHIVE_PREVIOUS_KEYS vollständig?',
|
|
'unsigned_refused' => 'Tombstone-Export ohne Signatur — abgebrochen. Nur für einen Export von vor dem 29.09.2026 mit --accept-unsigned wiederholen.',
|
|
default => 'Kein Tombstone-Export — abgebrochen. Ohne ihn können gelöschte Einträge zurückkehren; bewusst mit --without-export.',
|
|
});
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$this->info(sprintf(
|
|
'%d Payload(s) ohne Zeile, %d wieder registriert, %d laut Tombstone-Export gelöscht (übergangen), %d fehlgeschlagen.',
|
|
$result['candidates'],
|
|
$result['registered'],
|
|
$result['skipped_tombstoned'],
|
|
$result['failed'],
|
|
));
|
|
|
|
if ($result['registered'] > 0) {
|
|
$this->warn('Legal Hold und Kennzahlen stehen nicht im Manifest — wiederhergestellte Einträge im Admin prüfen.');
|
|
}
|
|
|
|
return $result['failed'] > 0 ? self::FAILURE : self::SUCCESS;
|
|
}
|
|
}
|