feat(plugins): admin review panel for scanner findings

The overrideWarnings escape hatch added alongside the bundle scan was
API-only: an admin uploading a crypto plugin through the web form hit a
400 with canOverride and had no way to act on it, which left S/MIME and
PGP bundles uninstallable through the UI.

Hold the rejected file client-side and show the findings — pattern per
file — with "Install anyway" and "Cancel". Proceeding re-posts the same
file with overrideWarnings, so the decision stays explicit and lands in
the audit log. The route now echoes accepted findings back on success so
the confirmation says how many were waved through rather than reporting a
bare install.

Also replaces a dead `data.warnings` read with the live `findings` field;
the route never returned `warnings` on success, so that branch never ran.

Completes B-01.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bernd Rodler
2026-08-04 09:03:14 +02:00
co-authored by Claude Opus 4.8
parent d91db37b34
commit e9746fcf78
3 changed files with 78 additions and 8 deletions
+3 -1
View File
@@ -255,7 +255,9 @@ export async function POST(request: NextRequest) {
logger.warn('Plugin installed with scanner override', { id: plugin.id, findings });
}
return NextResponse.json({ plugin });
// Echo accepted findings back so the admin UI can confirm exactly what was
// waved through, rather than reporting a bare success.
return NextResponse.json(findings.length > 0 ? { plugin, findings } : { plugin });
} catch (error) {
logger.error('Plugin install error', { error: error instanceof Error ? error.message : 'Unknown error' });
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });