feat: Google Photos provider backend + API hardening
- Add Google Photos provider: client, models, change detector, capabilities - Add notification templates (en/ru) for all GP event slots - Add command templates (en/ru) for GP bot commands - Register GP in slot/command loaders, capabilities, and seeds - Harden provider API: validate OAuth credentials on create/update - Add internal URL rewriting for asset fetches (LAN optimization) - Fix template renderer to handle missing variables gracefully - Improve webhook command routing for multi-provider support - Add provider health check endpoint and watcher improvements
This commit is contained in:
@@ -11,8 +11,11 @@ from slowapi.middleware import SlowAPIMiddleware
|
||||
|
||||
# Ensure app-level loggers are visible
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.getLogger("notify_bridge_server").setLevel(logging.DEBUG)
|
||||
logging.getLogger("notify_bridge_core").setLevel(logging.DEBUG)
|
||||
|
||||
from .config import settings as _log_cfg
|
||||
_log_level = logging.DEBUG if _log_cfg.debug else logging.INFO
|
||||
logging.getLogger("notify_bridge_server").setLevel(_log_level)
|
||||
logging.getLogger("notify_bridge_core").setLevel(_log_level)
|
||||
|
||||
from .database.engine import init_db
|
||||
from .database.models import * # noqa: F401,F403 — ensure all models registered
|
||||
@@ -77,6 +80,24 @@ async def lifespan(app: FastAPI):
|
||||
|
||||
app = FastAPI(title="Notify Bridge", version="0.1.0", lifespan=lifespan)
|
||||
|
||||
# --- Security headers ---
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from starlette.requests import Request as StarletteRequest
|
||||
from starlette.responses import Response as StarletteResponse
|
||||
|
||||
|
||||
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(self, request: StarletteRequest, call_next):
|
||||
response: StarletteResponse = await call_next(request)
|
||||
response.headers["X-Content-Type-Options"] = "nosniff"
|
||||
response.headers["X-Frame-Options"] = "DENY"
|
||||
response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
|
||||
return response
|
||||
|
||||
|
||||
app.add_middleware(SecurityHeadersMiddleware)
|
||||
|
||||
# --- Rate limiting ---
|
||||
from .auth.routes import limiter
|
||||
app.state.limiter = limiter
|
||||
|
||||
Reference in New Issue
Block a user