Updating scripts to hopefully work with migrated DB.
All checks were successful
Build & Deploy Backend / build (push) Successful in 58s
Build & Deploy Backend / deploy (push) Successful in 32s

This commit is contained in:
2025-10-08 09:10:17 +08:00
parent 1da5d77e5c
commit 2517db791c
9 changed files with 74 additions and 20 deletions

View File

@@ -1,7 +1,7 @@
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=6DRR4xWvHBhSqLGtIOEKa7gHjKnX33Hf
DB_HOST=db.psg.net.au:3307
DB_USER=svc_sysinfo
DB_PASSWORD=2pT08pEuxqFiN6eD348vBlgoMfyfOjGB
DB_NAME=db_ld-spring-backend
NVD_API_KEY=42b4f093-e8c4-4110-a7d1-6ab2ba6234aa
NVD_MAX_RANGE_DAYS=30
NVD_MAX_RANGE_DAYS=30

View File

@@ -8,6 +8,7 @@ dotenv.config({ path: '.env.local' });
const DB = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,

View File

@@ -66,6 +66,7 @@ function addDaysToISO(dateISO, days) {
const DB = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,

View File

@@ -14,6 +14,7 @@ const logFile = fs.createWriteStream('cve-sync.log', {
const RESUME_FILE = '.enrichment_resume';
const DB = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,

View File

@@ -77,6 +77,7 @@ function addDaysToISO(dateISO, days) {
const DB = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,

View File

@@ -7,6 +7,7 @@ const KEV_URL = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_
const DB = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,

View File

@@ -9,6 +9,7 @@ dotenv.config({ path: '.env.local' });
const DB = await mysql.createConnection({
host: process.env.DB_HOST,
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,

View File

@@ -42,55 +42,69 @@ public class ScriptController {
@Value("${nvd.max-range-days:7}")
private String nvdMaxRangeDays;
private final File cveLogFile = new File("scripts/cve-sync.log");
private final File kevLogFile = new File("scripts/kev-sync.log");
private final File msrcLogFile = new File("scripts/msrc-sync.log");
@Value("${scripts.directory:/home/sonder/ld-sysinfo-server/scripts}")
private String scriptsDirectory;
@Value("${scripts.logs.directory:/home/sonder/ld-sysinfo-server/scripts}")
private String logsDirectory;
private File getCveLogFile() {
return new File(logsDirectory, "cve-sync.log");
}
private File getKevLogFile() {
return new File(logsDirectory, "kev-sync.log");
}
private File getMsrcLogFile() {
return new File(logsDirectory, "msrc-sync.log");
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/fetch-cve")
public ResponseEntity<String> runCveScript(@AuthenticationPrincipal Object user) {
return triggerScript("fetchCVE.js", "📡 CVE sync launched in background.", cveLogFile);
return triggerScript("fetchCVE.js", "📡 CVE sync launched in background.", getCveLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/fetch-kev")
public ResponseEntity<String> runKevScript(@AuthenticationPrincipal Object user) {
return triggerScript("fetchKEV.js", "📡 KEV sync launched in background.", kevLogFile);
return triggerScript("fetchKEV.js", "📡 KEV sync launched in background.", getKevLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/fetch-msrc")
public ResponseEntity<String> runMsrcScript(@AuthenticationPrincipal Object user) {
return triggerScript("enrichCVE_MSRC.js", "📡 MSRC sync launched in background.", msrcLogFile);
return triggerScript("enrichCVE_MSRC.js", "📡 MSRC sync launched in background.", getMsrcLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/fetch-cve/logs")
public ResponseEntity<String> fetchLogs(@AuthenticationPrincipal Object user) {
return readLogs(cveLogFile);
return readLogs(getCveLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/fetch-cve/clear-logs")
public ResponseEntity<String> clearLogs(@AuthenticationPrincipal Object user) {
return clearLogs(cveLogFile);
return clearLogs(getCveLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/fetch-kev/clear-logs")
public ResponseEntity<String> clearKevLogs(@AuthenticationPrincipal Object user) {
return clearLogs(kevLogFile);
return clearLogs(getKevLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/fetch-msrc/clear-logs")
public ResponseEntity<String> clearMsrcLogs(@AuthenticationPrincipal Object user) {
return clearLogs(msrcLogFile);
return clearLogs(getMsrcLogFile());
}
@PreAuthorize("hasRole('ADMIN')")
@GetMapping(value = "/fetch-cve/logs/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamLogs(@AuthenticationPrincipal Object user) {
Path logFile = Paths.get("scripts/cve-sync.log");
Path logFile = getCveLogFile().toPath();
return Flux.interval(Duration.ofSeconds(1))
.map(tick -> {
@@ -110,7 +124,7 @@ public class ScriptController {
@PreAuthorize("hasRole('ADMIN')")
@GetMapping(value = "/fetch-kev/logs/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamKevLogs(@AuthenticationPrincipal Object user) {
Path logFile = Paths.get("scripts/kev-sync.log");
Path logFile = getKevLogFile().toPath();
return Flux.<String>create(emitter -> {
final long[] lastKnownPosition = {0};
@@ -155,7 +169,7 @@ public class ScriptController {
@PreAuthorize("hasRole('ADMIN')")
@GetMapping(value = "/fetch-msrc/logs/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamMsrcLogs(@AuthenticationPrincipal Object user) {
Path logFile = Paths.get("scripts/msrc-sync.log");
Path logFile = getMsrcLogFile().toPath();
return Flux.interval(Duration.ofSeconds(1))
.map(tick -> {
@@ -174,7 +188,8 @@ public class ScriptController {
private ResponseEntity<String> triggerScript(String scriptName, String message, File targetLogFile) {
File scriptFile = new File("scripts", scriptName);
File scriptDir = new File(scriptsDirectory);
File scriptFile = new File(scriptDir, scriptName);
if (!scriptFile.exists()) {
return ResponseEntity.status(404).body("" + scriptName + " not found at: " + scriptFile.getAbsolutePath());
}
@@ -184,7 +199,7 @@ public class ScriptController {
}
private void runNodeScript(String scriptName, String startMessage, File logTarget) {
File scriptDir = new File("scripts");
File scriptDir = new File(scriptsDirectory);
File scriptFile = new File(scriptDir, scriptName);
if (!scriptFile.exists()) {
@@ -204,6 +219,7 @@ public class ScriptController {
Map<String, String> env = builder.environment();
env.put("DB_HOST", extractHost(dbUrl));
env.put("DB_PORT", extractPort(dbUrl));
env.put("DB_NAME", extractDbName(dbUrl));
env.put("DB_USER", dbUser);
env.put("DB_PASSWORD", dbPass);
@@ -235,7 +251,37 @@ public class ScriptController {
}
private String extractHost(String url) {
return url.replace("jdbc:mysql://", "").split(":")[0].split("/")[0];
String clean = url.replace("jdbc:mysql://", "").split("/")[0];
// Handle IPv6 addresses like [::1]:3307
if (clean.startsWith("[")) {
int closeBracket = clean.indexOf("]");
if (closeBracket > 0) {
return clean.substring(1, closeBracket);
}
}
// Handle standard host:port format
return clean.split(":")[0];
}
private String extractPort(String url) {
String clean = url.replace("jdbc:mysql://", "").split("/")[0];
// Handle IPv6: [::1]:3307
if (clean.contains("]:")) {
return clean.substring(clean.indexOf("]:") + 2);
}
// Handle standard: hostname:3307
if (clean.contains(":") && !clean.startsWith("[")) {
String[] parts = clean.split(":");
if (parts.length > 1) {
return parts[1];
}
}
return "3306"; // default MySQL port
}
private String extractDbName(String url) {

View File

@@ -42,6 +42,8 @@ server.ssl.key-store-type=PKCS12
# Script Controller (NVD) related
nvd.api.key=42b4f093-e8c4-4110-a7d1-6ab2ba6234aa
nvd.max-range-days=30
scripts.directory=/home/sonder/ld-sysinfo-server/scripts
scripts.logs.directory=/home/sonder/ld-sysinfo-server/scripts
# SMTP/Mail related
spring.mail.host=psg-net-au.mail.protection.outlook.com