Phase 1: Add ESLint/Prettier config + baseline auto-fixes

This commit is contained in:
Krystie
2026-03-22 11:00:25 +01:00
parent 41a0cdee7e
commit e2c67a8fe8
90 changed files with 4008 additions and 3066 deletions

View File

@@ -7,116 +7,116 @@ module.exports = function(ctx) {
// GET /config — Get notification configuration (sensitive data redacted)
router.get('/config', ctx.asyncHandler(async (req, res) => {
const notificationConfig = ctx.notification.getConfig();
// Return config without sensitive data
const safeConfig = {
enabled: notificationConfig.enabled,
providers: {
discord: {
enabled: notificationConfig.providers.discord?.enabled || false,
configured: !!notificationConfig.providers.discord?.webhookUrl
},
telegram: {
enabled: notificationConfig.providers.telegram?.enabled || false,
configured: !!(notificationConfig.providers.telegram?.botToken && notificationConfig.providers.telegram?.chatId)
},
ntfy: {
enabled: notificationConfig.providers.ntfy?.enabled || false,
configured: !!notificationConfig.providers.ntfy?.topic,
serverUrl: notificationConfig.providers.ntfy?.serverUrl || 'https://ntfy.sh'
}
const notificationConfig = ctx.notification.getConfig();
// Return config without sensitive data
const safeConfig = {
enabled: notificationConfig.enabled,
providers: {
discord: {
enabled: notificationConfig.providers.discord?.enabled || false,
configured: !!notificationConfig.providers.discord?.webhookUrl,
},
events: notificationConfig.events,
healthCheck: notificationConfig.healthCheck
};
res.json({ success: true, config: safeConfig });
telegram: {
enabled: notificationConfig.providers.telegram?.enabled || false,
configured: !!(notificationConfig.providers.telegram?.botToken && notificationConfig.providers.telegram?.chatId),
},
ntfy: {
enabled: notificationConfig.providers.ntfy?.enabled || false,
configured: !!notificationConfig.providers.ntfy?.topic,
serverUrl: notificationConfig.providers.ntfy?.serverUrl || 'https://ntfy.sh',
},
},
events: notificationConfig.events,
healthCheck: notificationConfig.healthCheck,
};
res.json({ success: true, config: safeConfig });
}, 'notifications-config-get'));
// POST /config — Update notification configuration
router.post('/config', ctx.asyncHandler(async (req, res) => {
const { enabled, providers, events, healthCheck } = req.body;
const notificationConfig = ctx.notification.getConfig();
const { enabled, providers, events, healthCheck } = req.body;
const notificationConfig = ctx.notification.getConfig();
// Validate provider webhook URLs and tokens
if (providers) {
if (providers.discord?.webhookUrl) {
try {
validateURL(providers.discord.webhookUrl);
} catch (validationErr) {
return ctx.errorResponse(res, 400, 'Invalid Discord webhook URL');
}
}
if (providers.telegram?.botToken) {
try {
validateToken(providers.telegram.botToken);
} catch (validationErr) {
return ctx.errorResponse(res, 400, 'Invalid Telegram bot token format');
}
}
if (providers.ntfy?.serverUrl) {
try {
validateURL(providers.ntfy.serverUrl);
} catch (validationErr) {
return ctx.errorResponse(res, 400, 'Invalid ntfy server URL');
}
}
if (providers.ntfy?.topic) {
const topicRegex = /^[a-zA-Z0-9_-]{1,64}$/;
if (!topicRegex.test(providers.ntfy.topic)) {
return ctx.errorResponse(res, 400, 'Invalid ntfy topic (alphanumeric, hyphens, underscores only, max 64 chars)');
}
// Validate provider webhook URLs and tokens
if (providers) {
if (providers.discord?.webhookUrl) {
try {
validateURL(providers.discord.webhookUrl);
} catch (validationErr) {
return ctx.errorResponse(res, 400, 'Invalid Discord webhook URL');
}
}
// Update enabled state
if (typeof enabled === 'boolean') {
notificationConfig.enabled = enabled;
}
// Update providers (only update provided fields)
if (providers) {
if (providers.discord) {
notificationConfig.providers.discord = {
...notificationConfig.providers.discord,
...providers.discord
};
}
if (providers.telegram) {
notificationConfig.providers.telegram = {
...notificationConfig.providers.telegram,
...providers.telegram
};
}
if (providers.ntfy) {
notificationConfig.providers.ntfy = {
...notificationConfig.providers.ntfy,
...providers.ntfy
};
if (providers.telegram?.botToken) {
try {
validateToken(providers.telegram.botToken);
} catch (validationErr) {
return ctx.errorResponse(res, 400, 'Invalid Telegram bot token format');
}
}
// Update events
if (events) {
notificationConfig.events = { ...notificationConfig.events, ...events };
}
// Update health check settings
if (healthCheck) {
const wasEnabled = notificationConfig.healthCheck?.enabled;
notificationConfig.healthCheck = { ...notificationConfig.healthCheck, ...healthCheck };
// Restart daemon if settings changed
if (healthCheck.enabled !== wasEnabled || healthCheck.intervalMinutes) {
if (notificationConfig.healthCheck.enabled) {
ctx.notification.startHealthDaemon();
} else {
ctx.notification.stopHealthDaemon();
}
if (providers.ntfy?.serverUrl) {
try {
validateURL(providers.ntfy.serverUrl);
} catch (validationErr) {
return ctx.errorResponse(res, 400, 'Invalid ntfy server URL');
}
}
if (providers.ntfy?.topic) {
const topicRegex = /^[a-zA-Z0-9_-]{1,64}$/;
if (!topicRegex.test(providers.ntfy.topic)) {
return ctx.errorResponse(res, 400, 'Invalid ntfy topic (alphanumeric, hyphens, underscores only, max 64 chars)');
}
}
}
await ctx.notification.saveConfig();
res.json({ success: true, message: 'Notification config updated' });
// Update enabled state
if (typeof enabled === 'boolean') {
notificationConfig.enabled = enabled;
}
// Update providers (only update provided fields)
if (providers) {
if (providers.discord) {
notificationConfig.providers.discord = {
...notificationConfig.providers.discord,
...providers.discord,
};
}
if (providers.telegram) {
notificationConfig.providers.telegram = {
...notificationConfig.providers.telegram,
...providers.telegram,
};
}
if (providers.ntfy) {
notificationConfig.providers.ntfy = {
...notificationConfig.providers.ntfy,
...providers.ntfy,
};
}
}
// Update events
if (events) {
notificationConfig.events = { ...notificationConfig.events, ...events };
}
// Update health check settings
if (healthCheck) {
const wasEnabled = notificationConfig.healthCheck?.enabled;
notificationConfig.healthCheck = { ...notificationConfig.healthCheck, ...healthCheck };
// Restart daemon if settings changed
if (healthCheck.enabled !== wasEnabled || healthCheck.intervalMinutes) {
if (notificationConfig.healthCheck.enabled) {
ctx.notification.startHealthDaemon();
} else {
ctx.notification.stopHealthDaemon();
}
}
}
await ctx.notification.saveConfig();
res.json({ success: true, message: 'Notification config updated' });
}, 'notifications-config-update'));
// POST /test — Test notification delivery
@@ -159,7 +159,7 @@ module.exports = function(ctx) {
res.json({
success: true,
history: notificationHistory.slice(0, limit),
total: notificationHistory.length
total: notificationHistory.length,
});
}
}, 'notifications-history'));
@@ -177,7 +177,7 @@ module.exports = function(ctx) {
res.json({
success: true,
lastCheck: notificationConfig.healthCheck.lastCheck,
containersMonitored: Object.keys(ctx.notification.getHealthState()).length
containersMonitored: Object.keys(ctx.notification.getHealthState()).length,
});
}, 'notifications-health-check'));