feat: v3.1.0 — Live Platform Foundation (Track E.1-E.3)

Major release introducing the Live Platform architecture:

- SQLite database backend with async operations and migrations (E.1)
- AES-256-GCM credential encryption with HKDF key derivation (E.1)
- OAuth Social Login with GitHub and Google (E.2)
- Site management API with encrypted credential storage (E.3)
- Per-user MCP endpoints at /u/{user_id}/{alias}/mcp (E.3)
- User API keys with bcrypt hashing (E.3)
- Auto-generated config snippets for 5 MCP clients (E.3)
- Dashboard: dark/light mode, RBAC, My Sites, Connect page
- Active background health checks
- 452 tests (up from 303), all passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
airano
2026-02-23 23:20:03 +03:30
parent 42ea75bcb3
commit 9e6f06d933
53 changed files with 8654 additions and 1820 deletions

View File

@@ -371,3 +371,37 @@ class TestDashboardCookieManagement:
break
assert cookie_header is not None
assert "mcp_dashboard_session=" in cookie_header
def test_dashboard_connect_page(monkeypatch):
"""Test that the /dashboard/connect page renders successfully without 500 errors."""
from server import create_multi_endpoint_app
from starlette.testclient import TestClient
import core.dashboard.routes
import core.site_api
import core.user_keys
app = create_multi_endpoint_app()
client = TestClient(app)
def mock_req(*args):
return {'user_id': 'abc', 'type': 'user'}, None
monkeypatch.setattr(core.dashboard.routes, '_require_user_session', mock_req)
async def mock_sites(*args):
return [{'alias': 'Test', 'plugin_type': 'dummy'}]
monkeypatch.setattr(core.site_api, 'get_user_sites', mock_sites)
class MockKeyMgr:
async def list_keys(self, *a):
return [{'id': '1', 'name': 'Key', 'key_prefix': 'prefix', 'scopes': 'all', 'use_count': 0}]
monkeypatch.setattr(core.user_keys, 'get_user_key_manager', lambda: MockKeyMgr())
resp = client.get('/dashboard/connect')
assert resp.status_code == 200
assert "Test" in resp.text
assert "Key" in resp.text