Initial commit: DashCaddy v1.0
Full codebase including API server (32 modules + routes), dashboard frontend, DashCA certificate distribution, installer script, and deployment skills.
This commit is contained in:
70
dashcaddy-api/routes/config/settings.js
Normal file
70
dashcaddy-api/routes/config/settings.js
Normal file
@@ -0,0 +1,70 @@
|
||||
const fsp = require('fs').promises;
|
||||
const { validateConfig } = require('../../config-schema');
|
||||
const { exists } = require('../../fs-helpers');
|
||||
|
||||
module.exports = function(ctx) {
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
// ===== DASHCADDY CONFIG ENDPOINTS =====
|
||||
// Server-side config storage for setup wizard (shared across all browsers/machines)
|
||||
|
||||
router.get('/config', ctx.asyncHandler(async (req, res) => {
|
||||
if (!await exists(ctx.CONFIG_FILE)) {
|
||||
return res.json({ setupComplete: false });
|
||||
}
|
||||
const data = await fsp.readFile(ctx.CONFIG_FILE, 'utf8');
|
||||
const config = JSON.parse(data);
|
||||
res.json(config);
|
||||
}, 'config-get'));
|
||||
|
||||
router.post('/config', ctx.asyncHandler(async (req, res) => {
|
||||
const incoming = req.body;
|
||||
|
||||
if (!incoming || typeof incoming !== 'object') {
|
||||
return ctx.errorResponse(res, 400, 'Invalid config object');
|
||||
}
|
||||
|
||||
// Merge with existing config so partial saves don't wipe fields
|
||||
let existing = {};
|
||||
if (await exists(ctx.CONFIG_FILE)) {
|
||||
try {
|
||||
existing = JSON.parse(await fsp.readFile(ctx.CONFIG_FILE, 'utf8'));
|
||||
} catch (_) { /* start fresh if file is corrupt */ }
|
||||
}
|
||||
const config = { ...existing, ...incoming };
|
||||
|
||||
// Merge nested dns object so partial dns updates don't wipe dns fields
|
||||
if (existing.dns && incoming.dns) {
|
||||
config.dns = { ...existing.dns, ...incoming.dns };
|
||||
}
|
||||
// Merge nested dnsServers object
|
||||
if (existing.dnsServers && incoming.dnsServers) {
|
||||
config.dnsServers = { ...existing.dnsServers, ...incoming.dnsServers };
|
||||
}
|
||||
|
||||
// Validate merged config against schema
|
||||
const { valid, errors, warnings } = validateConfig(config);
|
||||
if (!valid) {
|
||||
return ctx.errorResponse(res, 400, 'Config validation failed', { errors });
|
||||
}
|
||||
|
||||
// Add timestamp
|
||||
config.updatedAt = new Date().toISOString();
|
||||
|
||||
await fsp.writeFile(ctx.CONFIG_FILE, JSON.stringify(config, null, 2), 'utf8');
|
||||
ctx.loadSiteConfig(); // Refresh in-memory config
|
||||
ctx.log.info('config', 'Config saved', { path: ctx.CONFIG_FILE });
|
||||
|
||||
res.json({ success: true, message: 'Configuration saved', config, warnings });
|
||||
}, 'config-save'));
|
||||
|
||||
router.delete('/config', ctx.asyncHandler(async (req, res) => {
|
||||
if (await exists(ctx.CONFIG_FILE)) {
|
||||
await fsp.unlink(ctx.CONFIG_FILE);
|
||||
}
|
||||
res.json({ success: true, message: 'Configuration reset' });
|
||||
}, 'config-delete'));
|
||||
|
||||
return router;
|
||||
};
|
||||
Reference in New Issue
Block a user