diff --git a/scripts/.env.local b/scripts/.env.local index fddef40..3075fe7 100644 --- a/scripts/.env.local +++ b/scripts/.env.local @@ -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 \ No newline at end of file diff --git a/scripts/enrichCVE_MSRC.js b/scripts/enrichCVE_MSRC.js index f059d20..6a3ab00 100644 --- a/scripts/enrichCVE_MSRC.js +++ b/scripts/enrichCVE_MSRC.js @@ -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, diff --git a/scripts/fetchCVE.js b/scripts/fetchCVE.js index 70f7258..adf54fe 100644 --- a/scripts/fetchCVE.js +++ b/scripts/fetchCVE.js @@ -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, diff --git a/scripts/fetchCVE_v2.js b/scripts/fetchCVE_v2.js index 21f05dc..b3dfaa7 100644 --- a/scripts/fetchCVE_v2.js +++ b/scripts/fetchCVE_v2.js @@ -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, diff --git a/scripts/fetchCVE_withMORE.js b/scripts/fetchCVE_withMORE.js index 60d0013..78e5778 100644 --- a/scripts/fetchCVE_withMORE.js +++ b/scripts/fetchCVE_withMORE.js @@ -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, diff --git a/scripts/fetchKEV.js b/scripts/fetchKEV.js index 02cec7f..2826848 100644 --- a/scripts/fetchKEV.js +++ b/scripts/fetchKEV.js @@ -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, diff --git a/scripts/fetchMSRC.js b/scripts/fetchMSRC.js index 641a749..68ca579 100644 --- a/scripts/fetchMSRC.js +++ b/scripts/fetchMSRC.js @@ -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, diff --git a/src/main/java/com/psg/dlsysinfo/dl_sysinfo_server/controller/ScriptController.java b/src/main/java/com/psg/dlsysinfo/dl_sysinfo_server/controller/ScriptController.java index 71e5737..aa4ad74 100644 --- a/src/main/java/com/psg/dlsysinfo/dl_sysinfo_server/controller/ScriptController.java +++ b/src/main/java/com/psg/dlsysinfo/dl_sysinfo_server/controller/ScriptController.java @@ -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 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 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 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 fetchLogs(@AuthenticationPrincipal Object user) { - return readLogs(cveLogFile); + return readLogs(getCveLogFile()); } @PreAuthorize("hasRole('ADMIN')") @PostMapping("/fetch-cve/clear-logs") public ResponseEntity clearLogs(@AuthenticationPrincipal Object user) { - return clearLogs(cveLogFile); + return clearLogs(getCveLogFile()); } @PreAuthorize("hasRole('ADMIN')") @PostMapping("/fetch-kev/clear-logs") public ResponseEntity clearKevLogs(@AuthenticationPrincipal Object user) { - return clearLogs(kevLogFile); + return clearLogs(getKevLogFile()); } @PreAuthorize("hasRole('ADMIN')") @PostMapping("/fetch-msrc/clear-logs") public ResponseEntity 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 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 streamKevLogs(@AuthenticationPrincipal Object user) { - Path logFile = Paths.get("scripts/kev-sync.log"); + Path logFile = getKevLogFile().toPath(); return Flux.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 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 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 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) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index de73f5f..16d652b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -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