mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-30 19:02:16 +00:00
- Rewrite .github/workflows/desktop.yml: 2-job pipeline (validate + build-and-release) with rolling desktop-latest pre-release on push to main and stable desktop-v* releases - Add UpdateChecker component: checks for updates on startup + every 30 min, background download with progress bar, one-click relaunch - Configure Tauri updater: endpoints pointing to desktop-latest release, pubkey placeholder - Add tauri-plugin-process for relaunch support (Cargo.toml, lib.rs, package.json) - Add macOS Entitlements.plist for notarization (network + file access, no sandbox) - Add scripts/bump-desktop-version.sh for atomic version bumps across 3 config files - Add desktop/README.md with dev setup, auto-update architecture, signing docs - Update .gitignore for desktop/node_modules, dist, target - Configure macOS minimumSystemVersion, Windows timestampUrl - Include all Phase 14-21 work: agent hardening, RBAC, taint tracking, workflows, skills, knowledge graph, sessions, A2A, MCP templates, WASM sandbox, TUI dashboard, production tools, CLI expansion, API expansion, learning productionization, Tauri desktop app, and 10 new channels Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
80 lines
2.6 KiB
Python
80 lines
2.6 KiB
Python
"""Tests for security middleware -- HTTP security headers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import patch
|
|
|
|
from openjarvis.server.middleware import SECURITY_HEADERS, create_security_middleware
|
|
|
|
|
|
class TestSecurityHeaders:
|
|
"""Tests for security headers middleware."""
|
|
|
|
def test_headers_dict(self) -> None:
|
|
"""Verify SECURITY_HEADERS has all expected keys."""
|
|
expected_keys = {
|
|
"X-Content-Type-Options",
|
|
"X-Frame-Options",
|
|
"X-XSS-Protection",
|
|
"Strict-Transport-Security",
|
|
"Content-Security-Policy",
|
|
"Referrer-Policy",
|
|
"Permissions-Policy",
|
|
}
|
|
assert set(SECURITY_HEADERS.keys()) == expected_keys
|
|
|
|
def test_create_middleware_without_starlette(self) -> None:
|
|
"""When starlette is not available, returns None."""
|
|
import importlib
|
|
|
|
import openjarvis.server.middleware as mod
|
|
|
|
blocked = {
|
|
"starlette": None,
|
|
"starlette.middleware": None,
|
|
"starlette.middleware.base": None,
|
|
"starlette.requests": None,
|
|
"starlette.responses": None,
|
|
}
|
|
with patch.dict("sys.modules", blocked):
|
|
importlib.reload(mod)
|
|
result = mod.create_security_middleware()
|
|
assert result is None
|
|
# Reload again to restore normal state
|
|
importlib.reload(mod)
|
|
|
|
def test_create_middleware_with_starlette(self) -> None:
|
|
"""When starlette is available, returns a class."""
|
|
middleware_cls = create_security_middleware()
|
|
if middleware_cls is None:
|
|
# starlette not installed -- skip
|
|
import pytest
|
|
pytest.skip("starlette not available")
|
|
assert middleware_cls is not None
|
|
assert callable(middleware_cls)
|
|
|
|
def test_middleware_adds_headers(self) -> None:
|
|
"""Middleware adds all security headers to responses."""
|
|
import pytest
|
|
fastapi = pytest.importorskip("fastapi")
|
|
from fastapi.testclient import TestClient
|
|
|
|
app = fastapi.FastAPI()
|
|
|
|
middleware_cls = create_security_middleware()
|
|
assert middleware_cls is not None
|
|
app.add_middleware(middleware_cls)
|
|
|
|
@app.get("/test")
|
|
def test_endpoint() -> dict:
|
|
return {"ok": True}
|
|
|
|
client = TestClient(app)
|
|
resp = client.get("/test")
|
|
assert resp.status_code == 200
|
|
|
|
for header_name, header_value in SECURITY_HEADERS.items():
|
|
assert resp.headers.get(header_name) == header_value, (
|
|
f"Missing or wrong header: {header_name}"
|
|
)
|