Merge krystie-improvements into main

Resolves 24 conflicts between Hermes (DC-008/009/010 + response-helper
envelope standardization) and Krystie (DC-005 src/ refactor path fixes,
DC-006 TOTP integration, DC-007 new test suites, cloud backup
destinations).

Conflict resolutions:
- src/utils/logging.js:    took ours (consumers depend on logError/
                            safeErrorMessage/createLogger exports)
- src/config/site.js:      merged (her factored validateAndLogConfig +
                            applyConfigFields helpers)
- src/context/dns.js:      took hers (admin/readonly role iteration for
                            write operations)
- src/utilities/backup-
  manager.js:              took hers (Dropbox/WebDAV/SFTP cloud feature)
- status/dist/*, status/
  sw.js:                   took hers (minified bundles + newer SW cache)

Additional fix (post-merge regression):
- src/monitoring/health-checker.js: fixed DC-005 path miss —
  'require(./platform-paths)' → 'require(../../platform-paths)'

Test status: 921/922 passing. One known failure in logging.test.js
(async file-handle timing) tracked as follow-up.
This commit is contained in:
Hermes
2026-06-25 16:43:10 -07:00
171 changed files with 11759 additions and 1006 deletions
+9 -8
View File
@@ -1,8 +1,9 @@
const express = require('express');
const fs = require('fs');
const { CADDY, REGEX, LIMITS } = require('../constants');
const { ValidationError, ConflictError, NotFoundError } = require('../errors');
const { validateURL } = require('../input-validator');
const { CADDY, REGEX, LIMITS } = require('../src/utilities/constants');
const { ValidationError, ConflictError, NotFoundError } = require('../src/utilities/errors');
const { validateURL } = require('../src/security/input-validator');
const { ok, successMessage } = require('../src/utils/responses');
/**
* Sites route factory
@@ -49,7 +50,7 @@ module.exports = function({ asyncHandler, ok, caddy, dns, fetchT, buildDomain, a
throw new Error('Caddy reload failed. Check server logs for details.');
}
ok(res, { message: 'Caddy configuration reloaded successfully' });
successMessage(res, 'Caddy configuration reloaded successfully');
}, 'caddy-reload'));
// Get Certificate Authorities from Caddyfile
@@ -127,7 +128,7 @@ module.exports = function({ asyncHandler, ok, caddy, dns, fetchT, buildDomain, a
name: ca.name,
displayName: ca.name !== (ca.id || ca.name) ? `${ca.name} (${ca.id || ca.name})` : ca.name
}));
res.json({ status: 'success', data: { cas: caList } });
ok(res, { cas: caList });
}, 'caddy-get-cas'));
// Remove a site from Caddyfile
@@ -152,7 +153,7 @@ module.exports = function({ asyncHandler, ok, caddy, dns, fetchT, buildDomain, a
throw new NotFoundError(`Site block for "" in Caddyfile`);
}
ok(res, { message: `Site "${domain}" removed from Caddyfile and Caddy reloaded` });
successMessage(res, `Site "${domain}" removed from Caddyfile and Caddy reloaded`);
}, 'site-delete'));
// Add a new site to Caddyfile and reload
@@ -180,7 +181,7 @@ module.exports = function({ asyncHandler, ok, caddy, dns, fetchT, buildDomain, a
result.rolledBack ? { note: 'Caddyfile was rolled back to previous state' } : {});
}
ok(res, { message: `Site "${domain}" added to Caddyfile and Caddy reloaded successfully` });
successMessage(res, `Site "${domain}" added to Caddyfile and Caddy reloaded successfully`);
}, 'site-add'));
// Add external service reverse proxy to Caddyfile
@@ -205,7 +206,7 @@ module.exports = function({ asyncHandler, ok, caddy, dns, fetchT, buildDomain, a
if (createDns) {
try {
await dns.createRecord(subdomain, siteConfig.dnsServerIp);
await dns.universalCreateRecord(subdomain, siteConfig.dnsServerIp);
log.info('dns', 'DNS record created for external proxy', { domain, ip: siteConfig.dnsServerIp });
} catch (dnsError) {
dnsWarning = `DNS creation failed: ${dnsError.message}. You may need to create the DNS record manually.`;