fix: P0/P1 audit fixes — DDNS correctness, peer provisioning gates, honest stubs
CloudflareDDNS.update() was calling the wrong endpoint; fix to use the correct zone-records API so DDNS updates actually land. NoIP and FreeDNS providers now return explicit "not implemented" errors instead of silently claiming success, preventing false-positive health state. PicNgoDNS ACME dns-challenge now sends the token in the request body (was missing), so cert issuance no longer silently fails. add_peer gates builtin-service provisioning on the installed-services list so a freshly-provisioned peer does not attempt to configure services that aren't present, eliminating the startup error loop. Startup Caddyfile regeneration added to routes/config.py so that a stale on-disk Caddyfile no longer triggers the health-monitor restart loop after a config change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -660,6 +660,22 @@ def ddns_register():
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@bp.route('/api/ddns/sync', methods=['POST'])
|
||||
def ddns_sync_records():
|
||||
"""Sync per-service public DNS records (Cloudflare provider)."""
|
||||
try:
|
||||
from app import ddns_manager
|
||||
from ddns_manager import DDNSError
|
||||
try:
|
||||
result = ddns_manager.sync_service_records()
|
||||
except DDNSError as exc:
|
||||
return jsonify({'error': str(exc)}), 400
|
||||
return jsonify(result)
|
||||
except Exception as e:
|
||||
logger.error('Error in /api/ddns/sync: %s', e)
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@bp.route('/api/config/pending', methods=['GET'])
|
||||
def get_pending_config():
|
||||
from app import config_manager
|
||||
|
||||
@@ -83,11 +83,16 @@ def add_peer():
|
||||
|
||||
provisioned = ['auth']
|
||||
domain = _configured_domain()
|
||||
# Only provision accounts on services that are actually installed —
|
||||
# email/calendar/files are optional store services.
|
||||
for step_name, step_fn in [
|
||||
('email', lambda: email_manager.create_email_user(peer_name, domain, password)),
|
||||
('calendar', lambda: calendar_manager.create_calendar_user(peer_name, password)),
|
||||
('files', lambda: file_manager.create_user(peer_name, password)),
|
||||
]:
|
||||
if step_name not in _installed:
|
||||
logger.debug(f"Peer {peer_name}: {step_name} not installed — skipping account provisioning")
|
||||
continue
|
||||
try:
|
||||
if step_fn():
|
||||
provisioned.append(step_name)
|
||||
|
||||
Reference in New Issue
Block a user