39 Commits
Author SHA1 Message Date
Juan Denis cdd6d0898d Drop the unused schedule and passlib packages
Each survived as a single import nothing called: scheduling moved to
the job runner, and the FTP service never used sha512_crypt.
2026-10-26 01:44:23 -04:00
Juan Denis 13c34f3f8f Drop the unused apispec-webframeworks dependency
Nothing imports it; the OpenAPI service builds its spec with apispec
and its marshmallow plugin only.
2026-10-10 18:34:42 -04:00
Juan Denis b739a6b17e Drop gevent and the stale backend Dockerfile
The panel runs async_mode='threading' under a plain threaded gunicorn
worker; nothing imports gevent. It was still installed everywhere, and
on Python 3.14 (no wheel yet) its source build is what broke installs
in issue #148. backend/Dockerfile was unreferenced and still launched
the gevent-websocket worker that double-answers the WS handshake; the
run.py hint recommended the same worker.
2026-10-10 13:40:55 -04:00
Juan Denis 882726bd6f Bump Werkzeug to 3.1.9 for CVE-2026-102598 2026-10-09 00:33:56 -04:00
Juan Denis 94619c2d81 Bump PyJWT to 2.15.1 for security advisories
Clears the open PyJWT Dependabot alerts (HS/asymmetric key
confusion bypasses, empty HMAC keys, JWKS redirect/fetch issues,
RecursionError DoS, is_pem_format ReDoS, options-dict mutation).
2026-10-01 22:04:09 -04:00
Juan Denis add2f713a5 feat(ai): use Prompture 1.11 native gateway streaming 2026-09-08 00:47:58 -04:00
Juan Denis 569b052659 feat(ai): expose Prompture providers and saved connections 2026-09-08 00:42:54 -04:00
Juan Denis 232c6978c5 feat(connect): hold a live outbound connection to the relay
- app/services/connect_client.py: RelayClient background thread (WS hello
  signed device_id|ts|nonce, 20s pings, jittered 1s->60s backoff with reset
  after 2 stable minutes, >6 reconnects/10min flap log, close-code ->
  state_reason mapping, terminal revoked, long-poll fallback with 15min WS
  re-probe); connect-state.json runtime state merged into status();
  disconnect() stops the client and removes the state file; run_doctor()
  implements the connect check table
- app/services/connect_keys.py: strict load_keypair() for the transport
- app/__init__.py: start_client_if_paired() next to the linked-panel hook
- cli.py: connect status shows transport/last-seen/relay-instance; new
  connect doctor command (exit 1 on hard-check failure)
- requirements.txt: websockets==15.0.1 (WS client; the SocketIO stack is
  server-side only)
- tests/test_connect_relay.py: 21 unit tests for backoff, flap detection,
  close-code mapping, hello signature, state file, loop transitions
2026-09-02 10:31:26 -04:00
Juan DenisandClaude Opus 5 fcdd802fc5 chore(deps): bump marshmallow pin to 3.26.2
Patch bump on the pin used by the apispec/OpenAPI docs stack.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 12:06:01 -04:00
Juan Denis 3c25680351 feat(api): add typed endpoint contracts and envelopes 2026-08-18 02:47:57 -04:00
Juan DenisandClaude Opus 5 4b0bbf9864 deps: SQLAlchemy 2.0.52 — 2.0.23 cannot import on Python 3.13
Required for Debian 13 (issue #99), which ships only python3.13. SQLAlchemy
2.0.23 installs there and then dies at import:

    AssertionError: Class <class 'sqlalchemy.sql.elements.SQLCoreOperations'>
    directly inherits TypingOnly but has additional attributes
    {'__static_attributes__', '__firstlineno__'}

3.13 adds those two class attributes and SQLAlchemy's TypingOnly guard rejected
anything it did not expect. Fixed upstream in 2.0.31.

Measured rather than assumed, because this pin sits under every query in the
app. Full backend suite on Python 3.11 with 2.0.52: 3542 passed, 48 skipped —
byte-identical to the same suite on 2.0.23. Run against a throwaway overlay so
the comparison was pins-only, nothing else moved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 11:55:11 -04:00
Juan Denis 00c66556b0 Bump cryptography to 50.0.0
Update the backend dependency pin from `cryptography==48.0.1` to `cryptography==50.0.0` in `requirements.txt` to keep encryption tooling current.
2026-08-04 09:10:56 -04:00
Juan Denis 7104713b8e Add pip-audit CI gate and bump click
Make dependency scanning reliable in CI by adding a blocking pip-audit job for the backend and test harness requirements, while keeping Safety as a non-blocking advisory check because third-party service failures should not block merges. Also bump `click` to `8.3.3` to address the reported vulnerability in a directly pinned dependency.
2026-07-20 02:16:47 -04:00
Juan DenisandClaude Fable 5 9e68202fae fix(deps): bump python-socketio to 5.16.3 and python-engineio to 4.13.3
Resolves Safety scan DoS advisories SFTY-20260626-04169 (socketio) and
SFTY-20260626-60054 / SFTY-20260626-39072 (engineio). Verified compatible
with Flask-SocketIO 5.6.1 under async_mode='threading'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 02:49:48 -04:00
Juan DenisandClaude Fable 5 751dde7a7d fix(deploy): threaded gunicorn worker — gevent-websocket class broke WebSocket
The app runs flask-socketio with async_mode='threading' (the backend
is real-thread based: jobs scheduler, queue bus, agent registry), where
engineio serves WebSocket via simple-websocket on the raw socket. The
systemd unit template and Dockerfile still launched gunicorn with the
GeventWebSocketWorker, which ALSO answers the upgrade — the client got
HTTP/1.1 101 twice and read the second one as a frame ('Invalid frame
header'), so every panel silently degraded to polling. Proven by
hexdump (double 101, first 'frame' byte 0x48 'H') and fixed live:
single 101 + 0x81 text frame, socket.io connects through Cloudflare.

- unit template + Dockerfile: gunicorn -w 1 --threads 100 (single
  PROCESS stays mandatory — in-memory agent gateway)
- requirements: pin simple-websocket explicitly (was transitive-only)
- CLAUDE.md / ARCHITECTURE.md / SECURITY.md single-worker notes updated

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 00:14:49 -04:00
Juan DenisandClaude Opus 4.8 e3249fbd52 fix(system): report IANA timezone_id; guard chart formatting against bad zones
SystemService.get_server_time fell through to Python's time.tzname on hosts
without /etc/timezone or timedatectl (e.g. Windows dev), yielding a display
name like "Eastern Daylight Time" — not a valid IANA/Intl key. The dashboard
MetricsGraph then crashed with RangeError: Invalid time zone specified.

- Backend: add a cross-platform tzlocal fallback + an IANA-validity guard so
  timezone_id is always an IANA key or null (display name stays in
  timezone_name). Declare tzlocal in requirements.
- Frontend: MetricsGraph validates the zone and falls back to local time
  instead of throwing (defense in depth).
- Test: test_server_time_timezone.py.

ServerKit's timezone feature (get/list/set via /api/v1/system/timezone) is
unchanged — this only fixes the value reported on non-Linux hosts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:55:11 -04:00
Juan Denis 4a02b5f3f6 fix: Python 3.10 tomllib fallback, alembic logging, and frontend compose healthcheck 2026-06-22 18:12:50 -04:00
Juan Denis 47c92e0571 feat(auth): WebAuthn / Passkey support
- Add webauthn dependency.
- Add PasskeyCredential model and Alembic migration 019_passkey_credentials.
- Add PasskeyService for registration/authentication challenge flow.
- Add auth API endpoints:
  - POST /auth/passkeys/options/register
  - POST /auth/passkeys/register
  - GET /auth/passkeys
  - DELETE /auth/passkeys/<id>
  - POST /auth/passkeys/options/authenticate
  - POST /auth/passkeys/authenticate
- Expose passkey_enabled flag in User.to_dict().
2026-06-19 01:33:45 -04:00
Juan DenisandClaude Opus 4.8 3a8fafcba4 chore(deps): bump PyJWT 2.13.0 + cryptography 48.0.1 (Safety advisories)
The Safety dependency scan flagged PyJWT==2.12.1 (5 vulns) and
cryptography==46.0.7 (1 vuln, bundled-OpenSSL). Bump to the Safety-suggested
fixes, which resolve all 6 currently-active (non-policy-ignored) findings.
Verified: installs with no resolver conflicts, the Fernet/encryption tests
pass, the app boots (JWT manager), and the full suite is 232 passed / 12
skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 23:47:15 -04:00
Juan DenisandClaude Opus 4.8 9cab065dc5 feat(ai): add core AI assistant primitive powered by Prompture
AI is a core ServerKit primitive (not a plugin): an Intercom-style bubble + slide-in drawer on every dashboard page, with a tools+page-context assistant mode and a plain simple chat mode, SSE streaming, conversation persistence, and guarded write actions (the model proposes; the user approves).

Plugins EXTEND the assistant rather than rebuilding it: backend via app.plugins_sdk.ai (reg.tool + register_context_provider, discovered from a plugin.json ai block with install/enable/disable hooks); frontend via useServerkitAI() and a contributions.ai category (suggested_prompts, tool_renderers). The marketplace gains an ai category for discovery.

Backend: ai_service (Prompture Conversation + ProviderEnvironment + guardrails), ai_tool_registry singleton, ai_tools_builtin (core.* tools), the /api/v1/ai blueprint (SSE via a worker-thread + queue bridge, single-gevent-worker safe; in-thread confirmation gate), AiConversation/AiMessage/AiPendingAction models + migration 013, encrypted ai_* settings. Frontend: AIContext + components/ai/*, AI settings tab. Powered by Prompture (installed editable; requirements pinned).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 02:39:05 -04:00
Juan DenisandClaude Opus 4.8 9e511caba7 fix(deps): bump Authlib 1.6.11 -> 1.6.12 (CVE-2026-44681)
Safety flagged Authlib 1.6.11 for CVE-2026-44681 (MEDIUM): an open-redirect
via insufficient redirect_uri validation in the OAuth flow — directly
relevant since Authlib backs the SSO/OAuth login. 1.6.12 is the upstream fix
(patch bump, same 1.6.x line, lowest risk to the SSO code).

Authlib was pinned twice in requirements.txt; bumped both so they don't drift
into conflicting exact pins.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:06:58 -04:00
Juan DenisandClaude Opus 4.8 6525e66a83 fix(backend): auto-allow SERVERKIT_PUBLIC_URL in CORS; bump Flask-SocketIO
When the panel sits behind a reverse proxy / tunnel, browsers and agents
arrive from SERVERKIT_PUBLIC_URL. Without that origin in CORS_ORIGINS the
engine.io WS handshake rejects it and every Socket.IO connection 400s with
"not an accepted origin". Auto-append SERVERKIT_PUBLIC_URL (deduped,
whitespace-stripped) so operators configure the public URL in one place.
Also bumps Flask-SocketIO 5.4.1 -> 5.6.1. Recovered from a local stash.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 19:44:47 -04:00
Juan DenisandCopilot 05a70f1a3b Bump vulnerable backend deps flagged by Safety
- python-dotenv 1.0.0 -> 1.2.2 (CVE-2026-28684, arbitrary file overwrite via symlinks)
- cryptography 46.0.5 -> 46.0.7 (CVE-2026-39892 buffer overflow, CVE-2026-34073 cert validation)
- requests 2.32.5 -> 2.33.1 (CVE-2026-25645, insecure temp file reuse)
- Authlib 1.6.9 -> 1.6.11 (CVE: missing CSRF protection)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-29 03:14:25 -04:00
Juan Denis 761c27471a Bump PyJWT to 2.12.1 in backend requirements
Update backend/requirements.txt to upgrade PyJWT from 2.8.0 to 2.12.1. This brings the JWT dependency to a newer release for bug fixes and improved compatibility with the authentication stack.
2026-03-23 17:58:01 -04:00
Juan Denis d2d87ecc1d Add workflow engine, models, API & UI
Introduce a full-featured workflow automation system: add WorkflowEngine service to execute workflows, background scheduler to trigger cron workflows, and croniter dependency. Extend Workflow model with automation fields (is_active, trigger_type, trigger_config, last_run_at, last_status) and add WorkflowExecution and WorkflowLog models. Add API endpoints to start executions, list executions, fetch execution details and logs, and persist execution records/logs. Implement frontend components for workflow nodes, config panels, and an execution history UI (multiple new React components) and wire minor builder UI imports. Note: database migrations are required to add new columns and tables.
2026-03-23 01:10:28 -04:00
Juan Denis 0aeb1634f4 Bump Authlib to 1.6.9
Update backend/requirements.txt to upgrade Authlib from 1.5.2 to 1.6.9. Verify SSO/OAuth flows and run tests to ensure compatibility with the newer Authlib release.
2026-03-04 02:59:45 -05:00
Juan Denis c5710e88b9 Add API keys, analytics, webhooks, and middleware
Introduce programmatic API features and observability: add API Key management, API usage analytics, webhook event subscriptions, and OpenAPI docs. New models (ApiKey, ApiUsageLog, ApiUsageSummary, EventSubscription, EventDelivery), services (api_analytics, api_key, event, openapi), and blueprints (/api-keys, /api-analytics, /event-subscriptions, /docs) were added and registered in create_app. Middleware for API key authentication, buffered analytics logging (with a flush thread), and enhanced rate limiting (custom key function and response headers) were implemented; RBAC was updated to accept API key auth via an auth_required decorator. Background threads for hourly aggregation and event retry were added; security CSP updated to allow resources for Swagger UI. Frontend settings UI and styles were added/updated for API keys and webhooks, and requirements were updated.
2026-03-04 01:53:46 -05:00
Juan Denis 08d5c4bade Add SSO/OAuth and DB migration framework
Add full SSO (Google, GitHub, generic OIDC, SAML) support and integrate Alembic-based DB migrations. Introduces OAuthIdentity model, sso_service, SSO API blueprint (authorize/callback/link/unlink/admin/config/test), and settings to enable/configure providers and enforce SSO-only logins. Integrates Flask-Migrate and a MigrationService with API endpoints for status/backup/apply/history and includes Alembic scaffolding (migrations/versions/001_baseline.py). Update app init to register SSO and migrations blueprints and initialize Migrate; replace fragile auto-column hack with MigrationService.prepare/check. Update User model (nullable password_hash, auth_provider, has_password/to_dict fields), add AuditLog SSO actions, add frontend SSO components/pages and a migration UI, and update ROADMAP and requirements. Notes: token encryption uses Fernet derived from SECRET_KEY; migrations may add the new auth_provider column at startup.
2026-03-04 01:37:22 -05:00
Piya f0e640237a feature: add backups storage provider
Align backups API, services, frontend, and dev scripts for new backup storage functionality.

Made-with: Cursor
2026-03-03 02:56:51 +07:00
Juan Denis 54e6e023a2 Bump Flask and Werkzeug versions
Update backend/requirements.txt to upgrade Flask from 3.0.0 to 3.1.3 and Werkzeug from 3.1.5 to 3.1.6. Applies minor/patch updates for bug fixes and dependency compatibility in the backend.
2026-03-01 13:43:11 -05:00
Juan Denis e5498af764 Fix remaining vulnerable dependencies flagged by Safety CI
- Werkzeug 3.0.1 → 3.1.5 (5 vulnerabilities)
- Flask-Cors 5.0.1 → 6.0.2 (3 vulnerabilities)
- gunicorn 22.0.0 → 23.0.0 (TolerateDangerousFraming header issue)
- cryptography 44.0.3 → 46.0.5 (CVE-2026-26007 improper input validation)
2026-02-11 23:13:28 -05:00
Juan Denis 9604e1ea66 Add Bandit + Safety security scanning to CI and fix vulnerable deps
- Add .github/workflows/security-scan.yml with Bandit SAST and Safety
  dependency scanning (requires SAFETY_API_KEY secret)
- Add backend/.bandit config to skip expected noise (B404, B603, B607)
- Update vulnerable dependencies:
  gunicorn 21.2.0 → 22.0.0 (CVE-2024-1135 HTTP smuggling)
  gevent 23.9.1 → 25.4.2 (HTTP smuggling + race condition)
  python-socketio 5.10.0 → 5.14.0 (CVE-2025-61765 deserialization)
  cryptography 42.0.0 → 44.0.3 (multiple CVEs)
  requests 2.31.0 → 2.32.5 (vulnerability fixes)
  Flask-Cors 4.0.0 → 5.0.1, Flask-SocketIO 5.3.6 → 5.4.1
  python-engineio 4.8.1 → 4.11.2
- Pin previously unpinned deps: schedule, passlib, bcrypt
2026-02-11 23:06:14 -05:00
Juan Denis 7833d78fc5 Add notification webhooks support (Discord, Slack, etc.)
Introduces backend and frontend support for notification webhooks, including Discord, Slack, Telegram, and generic webhooks. Adds new API endpoints for managing and testing notification channels, updates monitoring service to send alerts to these channels, and provides a new UI for configuring and testing notification integrations in settings. Also adds required styles and updates dependencies to include the requests library.
2026-01-18 01:13:30 -05:00
Juan Denis 3f5746cfe4 Add two-factor authentication (2FA) support
Implements TOTP-based two-factor authentication for user accounts. Adds backend endpoints and services for 2FA setup, confirmation, disabling, backup code management, and login verification. Updates the User model with 2FA fields and logic. Extends frontend login and settings pages to support 2FA flows, including modals for setup, disabling, and backup code management. Adds new styles for 2FA UI components. Updates requirements to include pyotp and qrcode.
2026-01-18 01:03:56 -05:00
Juan Denis e9455a7167 Add environment variable management feature
Introduces backend and frontend support for encrypted environment variable management, including CRUD API endpoints, history tracking, bulk import/export, and UI components. Updates requirements to include cryptography, and adds related documentation for competitive analysis, feature gaps, and market positioning.
2026-01-18 00:40:41 -05:00
Juan Denis 9def699bee Add firewall management API and service
Introduces backend API endpoints and service logic for managing firewalld and ufw, including status, rules, IP blocking, and installation. Updates CORS settings, improves Windows compatibility in file and FTP services, and adds required dependencies. Frontend changes include new Firewall and PHP pages, updated sidebar, and related styles.
2026-01-17 13:05:39 -05:00
Juan Denis c1d60f112f Add ServerKit CLI, install script, and deployment improvements
Introduces a comprehensive Bash CLI tool (`serverkit`) for managing ServerKit services, users, and database operations. Adds a quick-install script (`install.sh`) for Ubuntu, a sample environment file (`.env.example`), and a Python CLI backend (`backend/cli.py`) for administrative tasks. Updates Docker Compose for production readiness, enhances deployment documentation, and adds Click to backend requirements. Also updates references to the correct GitHub repository.
2026-01-17 12:13:22 -05:00
Juan Denis f677d760dd Add backup, monitoring, and deployment APIs
Introduces new API endpoints and services for backups, monitoring, and Git deployment. Adds security middleware, account lockout on failed logins, and improves domain/SSL management. Updates Dockerfiles, deployment configs, and frontend to support new features and UI components.
2026-01-17 12:08:02 -05:00
Juan Denis c0a2a01fc1 Initial project structure and core API implementation
Add backend and frontend foundations for ServerKit, including Flask API structure, SQLAlchemy models, service layers, and React app with authentication context and service hooks. Implement core API endpoints for authentication, application management, Docker, databases, and system operations. Update README with project overview, tech stack, and setup instructions. Add development roadmap and example environment configuration.
2026-01-17 04:22:12 -05:00