mirror of
https://github.com/LORDBABUINO/stealth.git
synced 2026-06-15 00:23:34 -07:00
Feat: Wire frontend to backend scan endpoint, replace UTXO report with findings
- Add GET /api/wallet/scan endpoint that shells out to detect.py - Add CORS config and detect.py script path to application.properties - walletService.js now calls the real scan endpoint instead of mock - Replace UtxoCard-based ReportScreen with FindingCard-based layout - FindingCard: collapsible card with data-driven details panel (address groups, string lists, key-value scalars) - VulnerabilityBadge: all 14 finding types labeled, severity lowercased, critical style added - ReportScreen: summary bar shows findings/warnings/txs analyzed; clean banner; separate warnings section
This commit is contained in:
@@ -23,6 +23,10 @@ Content-Type: application/json
|
||||
### Get UTXOs
|
||||
GET {{baseUrl}}/api/wallet/{{analyze.response.body.$.analysisId}}/utxos
|
||||
|
||||
### Scan descriptor
|
||||
# @name scan
|
||||
GET {{baseUrl}}/api/wallet/scan?descriptor={{descriptor}}
|
||||
|
||||
> {%
|
||||
client.test("status is 200", function() {
|
||||
client.assert(response.status === 200, "expected 200");
|
||||
|
||||
+37
@@ -1,20 +1,26 @@
|
||||
package org.backend.stealth.controller;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.backend.stealth.mocks.WalletMockData;
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ApplicationScoped
|
||||
@Path("/api/wallet")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class WalletResource {
|
||||
|
||||
@ConfigProperty(name = "stealth.detect.script", defaultValue = "../../script/detect.py")
|
||||
String detectScript;
|
||||
|
||||
private static final Map<String, String> sessions = new ConcurrentHashMap<>();
|
||||
|
||||
// DTOs
|
||||
@@ -64,4 +70,35 @@ public class WalletResource {
|
||||
}
|
||||
return Response.ok(WalletMockData.buildReport(descriptor)).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/scan")
|
||||
public Response scan(@QueryParam("descriptor") String descriptor) {
|
||||
if (descriptor == null || descriptor.isBlank()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "descriptor query parameter is required"))
|
||||
.build();
|
||||
}
|
||||
try {
|
||||
ProcessBuilder pb = new ProcessBuilder("python3", detectScript, descriptor);
|
||||
pb.redirectErrorStream(false);
|
||||
Process process = pb.start();
|
||||
|
||||
String output = new String(process.getInputStream().readAllBytes());
|
||||
int exitCode = process.waitFor();
|
||||
|
||||
if (exitCode != 0 || output.isBlank()) {
|
||||
String stderr = new String(process.getErrorStream().readAllBytes());
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", stderr.isBlank() ? "detect.py produced no output" : stderr.strip()))
|
||||
.build();
|
||||
}
|
||||
|
||||
return Response.ok(output).type(MediaType.APPLICATION_JSON).build();
|
||||
} catch (Exception e) {
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
quarkus.http.port=8080
|
||||
quarkus.http.cors=true
|
||||
quarkus.http.cors.origins=http://localhost:5173
|
||||
quarkus.http.cors.methods=GET,POST,OPTIONS
|
||||
quarkus.http.cors.headers=Content-Type,Accept
|
||||
|
||||
stealth.detect.script=../../script/detect.py
|
||||
|
||||
Reference in New Issue
Block a user