diff --git a/api/app.py b/api/app.py index 9aeb05f..c57945d 100644 --- a/api/app.py +++ b/api/app.py @@ -187,6 +187,13 @@ def enforce_setup(): return jsonify({'error': 'Setup required', 'redirect': '/setup'}), 428 +# Read-only endpoints accessible to peer-role sessions (not just admin). +# Add paths here when peers need to read shared cell state. +_PEER_READABLE_PATHS = frozenset({ + '/api/services/active', +}) + + @app.before_request def enforce_auth(): """Enforce session-based authentication and role-based access control. @@ -238,6 +245,8 @@ def enforce_auth(): if path.startswith('/api/peer/'): if role != 'peer': return jsonify({'error': 'Forbidden'}), 403 + elif path in _PEER_READABLE_PATHS: + pass # both admin and peer may read these endpoints else: if role != 'admin': return jsonify({'error': 'Forbidden'}), 403 diff --git a/api/service_store_manager.py b/api/service_store_manager.py index 55bf1df..48707c3 100644 --- a/api/service_store_manager.py +++ b/api/service_store_manager.py @@ -407,6 +407,19 @@ class ServiceStoreManager(BaseServiceManager): from firewall_manager import apply_service_rules installed = self.config_manager.get_installed_services() + + # Always regenerate the Caddyfile so a cell rename or fresh install + # produces the correct domain even when no store services are installed. + try: + caddy_routes = [ + r.get('caddy_route') + for r in (installed or {}).values() + if r.get('caddy_route') + ] + self.caddy_manager.regenerate_with_installed(caddy_routes) + except Exception as e: + logger.warning(f'reapply_on_startup: caddy regenerate failed: {e}') + if not installed: return @@ -419,17 +432,6 @@ class ServiceStoreManager(BaseServiceManager): except Exception as e: logger.warning(f'reapply_on_startup: apply_service_rules({svc_id}) failed: {e}') - # Regenerate Caddyfile - try: - caddy_routes = [ - r.get('caddy_route') - for r in installed.values() - if r.get('caddy_route') - ] - self.caddy_manager.regenerate_with_installed(caddy_routes) - except Exception as e: - logger.warning(f'reapply_on_startup: caddy regenerate failed: {e}') - # Bring up per-service compose stacks if self.service_composer is not None: try: