fix(config-history): only auto-snapshot devices with SSH configured; add settings UI (v0.17.4-beta)

Resolves #86 — MikroTik Manager was attempting SSH connections to devices that
have no SSH credentials configured, flooding RouterOS logs with failed logins.

Cause: config snapshots (a separate feature from scheduled backups, enabled by
default, hourly) capture `/export` over SSH via BackupService.exportConfig, which
silently falls back to the API credentials for the SSH login. On devices where
SSH was never set up, that auth fails every interval (and on each restart), and
there was no UI switch to turn it off.

- PollerService.processConfigSnapJob now skips devices without SSH credentials,
  so no SSH connection is attempted where SSH isn't configured. Manual "Capture
  snapshot" / backup actions are unchanged (user-initiated, with error feedback).
- Add a "Configuration Snapshots" section to Settings → General: enable toggle,
  interval, and retention (the feature was on-by-default with no UI control),
  with a note that it runs over SSH and only on devices that have SSH creds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2GT-Rich
2026-07-29 15:38:08 -07:00
co-authored by Claude Opus 4.8
parent 28701cfc67
commit f0176efd95
6 changed files with 68 additions and 4 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mikrotik-manager-backend",
"version": "0.17.3-beta",
"version": "0.17.4-beta",
"description": "Mikrotik Network Management Platform - Backend API",
"main": "dist/index.js",
"scripts": {
+6
View File
@@ -691,6 +691,12 @@ export class PollerService {
const device = await this.getDevice(data.deviceId);
if (!device) return;
// Config snapshots capture `/export` over SSH. Only attempt this automatically
// when SSH credentials are actually configured — otherwise we'd repeatedly try
// (and fail) SSH auth using the API credentials, flooding the device logs on
// devices where SSH was never set up. Manual "Capture snapshot" is unaffected.
if (!device.ssh_username || !device.ssh_password_encrypted) return;
const collector = new DeviceCollector(device);
try {
await collector.connect();