Phase 1: Fix all critical release blockers (B1-B10)

B1: Remove duplicate get_redis() — singleton no longer overwritten
B2: Plugin routes now enforce activation status via require_active_plugin()
B3: Fix UploadFile ForwardRef error — remove functools.wraps from wrap_plugin_route
B4: DMS upload uses true streaming via save_stream() instead of RAM accumulation
B5: Worker on_startup registers plugin event handlers + webhook dispatcher
B6: Implement send_password_reset_email job, remove raw token logging
B7: Webhook SSRF protection (IP validation, no redirects), secret removed from response
B8: RLS repair migration 0044 + separate crm_runtime DB user (NOSUPERUSER, NOBYPASSRLS)
B9: Fix .env.docker.example AUTH_SECRET → SECRET_KEY
B10: Remove Redis default password, remove exposed DB/Redis ports

Also: add frontend_url to config, add SMTP settings to .env.docker.example,
update prestart.sh to use MIGRATION_DATABASE_URL for alembic.
This commit is contained in:
Agent Zero
2026-07-26 20:45:42 +02:00
parent 7a14973c68
commit 5ec1fc9b05
32 changed files with 1781 additions and 76 deletions
+11 -2
View File
@@ -1,14 +1,19 @@
"""Plugin error isolation wrapper."""
import logging
import functools
from fastapi import UploadFile as _UploadFile # noqa: F401 — needed for ForwardRef resolution
from fastapi.responses import JSONResponse
logger = logging.getLogger(__name__)
def wrap_plugin_route(handler):
"""Decorator that isolates plugin route errors and returns structured JSON."""
@functools.wraps(handler)
"""Decorator that isolates plugin route errors and returns structured JSON.
Does NOT use functools.wraps to avoid copying __annotations__ and
__wrapped__ — FastAPI would otherwise try to resolve
``ForwardRef('UploadFile')`` from the original handler's signature.
"""
async def wrapper(*args, **kwargs):
try:
return await handler(*args, **kwargs)
@@ -18,4 +23,8 @@ def wrap_plugin_route(handler):
status_code=500,
content={'detail': f'Plugin error: {exc}', 'code': 'plugin_error'}
)
# Preserve identity for debugging but NOT __wrapped__ or __annotations__
wrapper.__name__ = getattr(handler, '__name__', 'wrapper')
wrapper.__module__ = getattr(handler, '__module__', __name__)
wrapper.__qualname__ = getattr(handler, '__qualname__', 'wrapper')
return wrapper