[glm-grade=B] fix: dead dashboard WS, corrupted error.log, auth-polling storm, re-auth freeze + CVE bumps
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s

Adversarial audit 2026-08-16 (GLM-5.3 delegate, 2 rounds, 141 tool calls):

P0-1: Dashboard WebSocket (/api/v1/ws) dead on EVERY boot since DC-076.
server.js passed module exports (DependencyManager class, {AutoRestartManager}
namespace, SSLMonitor class) instead of createApp()'s live instances — first
.on() threw ERR_INVALID_ARG_TYPE, catch swallowed it. Fix: app.locals.ctx
exposed in src/app.js; server.js passes all 8 real EventEmitter instances.

P0-2: error.log corrupted since 2026-07-14. errorMiddleware called
logError(FILE, SIZE, path, err, meta) — 5 args into a 3-arg wrapper —
logging 'Error: 5242880' garbage every ~60s and DISCARDING the real error
object. Fix: correct 3-arg call + legacy-shape guard in logErrorWrapper +
~74 log.error sites swept to pass real error objects (AST-verified scope-
safe 71/71, 29/29 modules load clean).

P0-3: auth-polling storm (stranded grade=B commit never landed in prod):
401/403 behind TOTP gate hammered /api/v1/services/status + SSE reconnect
every 2-8s, with misleading direct-probe fallback marking services 'up'.
Fix landed + B-round MEDIUM follow-up: TOTP re-auth success now clears
_dcAuthLost, resumes SSE (new _sseResume clears the latch), and refreshes.

Also: eslintignore static-sites/ (33→0 errors); nodemailer 8→9.0.5 and
sharp 0.33→0.35.3 (3 high CVEs killed; jest green on new majors);
dockerode@5/uuid deferred (semver-major, Docker API surface).

Verification: 80/80 suites, 1837/1837 tests; ESLint 0 errors/743 warnings;
node --check all changed files; bundles rebuilt + SW cache bumped.

Judges: Codex quota-dead until Aug 19 (verified live) — GLM adversarial
delegate per operator directive 2026-08-07. Round 1: 98-call mechanical
verification (timed out pre-verdict). Round 2 (this grade): B, one MEDIUM
(re-auth freeze) — fixed in this commit as prescribed.
This commit is contained in:
Krystie
2026-08-16 04:18:07 -07:00
parent 295c63ce94
commit e99413150e
39 changed files with 533 additions and 355 deletions
+3 -3
View File
@@ -95,7 +95,7 @@ module.exports = function({ docker, caddy, credentialManager, servicesStateManag
log.info('deploy', 'DashCA: For full features, copy certificate files to ' + destPath);
log.info('deploy', 'DashCA: Static site deployment completed successfully');
} catch (error) {
log.error('deploy', 'DashCA deployment error', { error: error.message });
log.error('deploy', error, null, { note: 'DashCA deployment error' });
throw new Error(`DashCA deployment failed: ${error.message}`);
}
}
@@ -231,7 +231,7 @@ module.exports = function({ docker, caddy, credentialManager, servicesStateManag
await portLockManager.releasePorts(lockId);
log.info('deploy', 'Port locks released after error', { lockId });
} catch (releaseError) {
log.error('deploy', 'Failed to release port locks', { lockId, error: releaseError.message });
log.error('deploy', releaseError, null, { note: 'Failed to release port locks', lockId });
}
}
throw deployError;
@@ -425,7 +425,7 @@ module.exports = function({ docker, caddy, credentialManager, servicesStateManag
} catch (error) {
try { await logError('app-deploy', error, { appId, config }); } catch (_) { /* logError failure should not mask original error */ }
const msg = error?.message || String(error || 'Unknown error');
log.error('deploy', 'Deployment failed', { appId, error: msg });
log.error('deploy', error, null, { note: 'Deployment failed', appId });
const template = ctx.APP_TEMPLATES[appId];
try { ctx.notification.send('deploymentFailed', 'Deployment Failed', `Failed to deploy **${template?.name || appId}**.\nError: ${msg}`, 'error'); } catch (_) {}
errorResponse(res, 500, ctx.safeErrorMessage(error));
+1 -1
View File
@@ -297,7 +297,7 @@ module.exports = function({ docker, caddy, servicesStateManager, asyncHandler, e
// P0-5 fix: was `errorResponse(res, 500, err.message)` which leaks internal
// error details (paths, stack traces, library error codes) to the client.
// Log the actual error server-side and return a generic message.
log.error('apps-revert', 'Revert failed', { error: err.message, stack: err.stack });
log.error('apps-revert', err, null, { note: 'Revert failed', stack: err.stack });
errorResponse(res, 500, 'Revert failed');
}
}, 'apps-revert'));
+1 -1
View File
@@ -148,7 +148,7 @@ module.exports = function({
}
} catch (error) {
results.caddy = `failed: ${error.message}`;
log.error('caddy', 'Caddy update error', { error: error.message });
log.error('caddy', error, null, { note: 'Caddy update error' });
}
try {