fix: DDNS update token in body, webdav gating, regression tests
Unit Tests / test (push) Successful in 7m25s

- PicNgoDDNS.update(): send token in request body instead of Authorization
  header; DDNS server validates it from body (was returning HTTP 422 on
  every heartbeat, leaving IP record stale after fresh install)
- peers.py / Peers.jsx: webdav service_access only valid when 'files' store
  service is installed; was always shown even with no services, confusing
  users into thinking WebDAV was pre-installed
- 10 new regression tests: DDNS update body contract, Caddy always
  regenerates on startup with no services, peer role allowed on
  /api/services/active, webdav gating by installed services

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 16:56:12 -04:00
parent 962d137093
commit 69862331e7
7 changed files with 241 additions and 12 deletions
+5 -1
View File
@@ -65,9 +65,13 @@ def add_peer():
except ValueError as e:
return jsonify({'error': str(e)}), 409
# 'webdav' is part of the 'files' store service (same container set);
# expose it only when 'files' is installed.
_STORE_ID_TO_ACCESS = {'email': 'mail', 'calendar': 'calendar', 'files': 'files'}
_installed = set(_app_cfg.get_installed_services() or {})
_valid_services = {'webdav'} | {_STORE_ID_TO_ACCESS[sid] for sid in _installed if sid in _STORE_ID_TO_ACCESS}
_valid_services = {_STORE_ID_TO_ACCESS[sid] for sid in _installed if sid in _STORE_ID_TO_ACCESS}
if 'files' in _installed:
_valid_services.add('webdav')
service_access = data.get('service_access', list(_valid_services))
if not isinstance(service_access, list) or not all(s in _valid_services for s in service_access):
return jsonify({"error": f"service_access must be a list of: {sorted(_valid_services)}"}), 400