Skip to content

Releases: BitaceS/talepanel

v0.11.0-beta

v0.11.0-beta Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 23 Oct 22:32

Off-site backups (OneDrive, Google Drive, Dropbox, S3, B2, SFTP, WebDAV), email setup in the panel, auto restart, CPU limits, and invitation roles that actually apply.

Security

  • The raw console now enforces the same roles as the quick commands. Before, anyone with server.console could type stop, op or any other command. Users may send help and world save, moderators also kick, ban, unban, whitelist, time, weather, teleport and say; everything else needs an admin. The server's own owner counts as admin on it.
  • Custom quick commands can no longer be saved with a lower min_role than the console command they run, and running one checks the resolved command as well, which also covers commands saved before this fix.
  • Granting or removing op on the Players page needs admin. The route only required player.ban, which moderators have.
  • Off-site backup destination credentials are AES-256-GCM encrypted with TOTP_ENC_KEY, never returned to the browser, and redacted from the audit log. Only a per-provider allowlist of rclone options is accepted; the daemon additionally refuses options that run commands or read local files. rclone gets its credentials from a per-operation 0600 config file, never from its command line.
  • Accepting a server invitation ignored the invited role: the member fell back to their global role, so an invited viewer could start the server and use the console. Accepting now grants the role's per-server permissions (viewer: view; moderator: power, console, mods, players, backup.create, database.view; admin: everything but delete), capped to what the inviter holds. Creating an invitation for a role with more rights than the inviter has returns 403. Revoking an invitation is limited to the server in the URL.
  • The CurseForge api_key was written to the audit log in plain text; it is redacted now.

Added

  • Quick setup for beginners: install.sh --quick (also the first menu entry, and the default when the script runs without a terminal) installs panel and game server on one machine with an sslip.io hostname and asks no questions. It prints a https://<host>/setup link and a one-time setup code; the first admin account is created in the browser. Only the code's SHA-256 is stored (SETUP_CODE_HASH in the panel .env).
  • POST /api/v1/setup/complete: creates the first owner with the setup code and signs it in. Works only while no account exists; concurrent attempts create exactly one owner. GET /health/setup reports setup_code_required.
  • Setup wizard at /setup: setup code, admin account, first Hytale server (optional). The login page sends visitors of a fresh install there.
  • tale-cli node enroll: mints a node enrollment token without a user account. Migration 036 makes node_enrollments.created_by optional.
  • Off-site backups: admins add destinations under Backups → Destinations — OneDrive, Google Drive, Dropbox, S3-compatible (AWS, Wasabi, Cloudflare R2, other), Backblaze B2, SFTP and WebDAV/Nextcloud. The node uploads each backup with rclone to <folder>/<server id>/<backup id>.zip. Per destination: keep a local copy or not, and keep the newest N uploads per server. For OneDrive/Google Drive/Dropbox the panel shows the rclone authorize command to run on your own computer and takes the pasted token; the OneDrive drive is looked up automatically. Refreshed OAuth tokens are saved back.
  • Backups and schedules can target a destination. The backup list shows where each backup is stored and its upload status (waiting, uploading, uploaded, upload failed with rclone's error); failed uploads can be retried. Restore and download fetch a backup from the destination when the node has no copy. Deleting a backup deletes its off-site copy.
  • "Test connection" for a destination writes and deletes a probe file and shows rclone's error text.
  • Daemon routes POST /servers/:id/backup/upload, /backup/remote-delete, POST /backup/download and POST /rclone/test; admin API /admin/backup-destinations (CRUD, /providers, /:id/test), GET /backup-destinations for the picker, POST /backups/:id/upload to retry. Migration 039.
  • The daemon image installs rclone 1.75.2 from downloads.rclone.org, checked against its SHA-256.
  • Email (SMTP) for alerts can be set up under Admin → Integrations, with a test-email button. Settings are stored encrypted and take effect without a restart; the SMTP_* env vars stay as fallback. New optional SMTP_TLS_MODE (starttls, tls, none).
  • Auto restart: a crashed server is started again after 5 s, 10 s, 20 s, up to 60 s; after 3 crashes in 10 minutes the daemon gives up. No restart after a stop from the panel, exit code 0, or Hytale exit codes 8 and 11.
  • CPU limit (% of one core, 0 = unlimited) is enforced with cgroup v2 where the daemon can write its cgroup. In the default Docker install it cannot; the daemon then logs a warning and writes a notice to the server console. Migration 038 resets the old default of 4 to 0.
  • A server that exited with Hytale exit code 8 or 11 shows a notice with a Reinstall button (POST /servers/:id/reinstall, needs server.manage). Migration 037 stores the last exit code.
  • The server's network role (none, hub, gamemode) can be set in the server's Settings tab.

Changed

  • MinIO is gone from the dev compose file, setup-dev.sh and .env.example.
  • A server that exits with code 0 without a stop from the panel (e.g. stop typed in the console) is marked stopped instead of crashed.
  • The "Storage" field of the backup and schedule forms (with its fake "S3 (MinIO)" option) is gone; storage in the API is accepted for compatibility and always stored as local. Use destination_id.
  • Backup downloads are streamed by the daemon instead of being read into memory first.
  • The Backups page no longer offers "All Servers" (the API only lists one server's backups) and preselects the first server.

Fixed

  • Email alerts on port 465 never sent (the notifier always tried STARTTLS), relays without a login failed because PLAIN auth was forced, and a send had no overall timeout.
  • An empty CPU field was stored as 4, which as a percentage would have throttled the server to 4% of a core.
  • Backups were never marked completed on a fresh database: the backup_status enum had complete, the code writes completed. Migration 039 adds the value.

v0.10.1-beta

v0.10.1-beta Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 22 Oct 19:05

Installer hotfix.

Fixed

  • The installer failed while pulling images: MinIO removed minio/minio and minio/mc from Docker Hub. MinIO was never used (backups stay on the node), so the panel stack no longer includes it. Upgrades remove the old MinIO containers; the minio_data volume is kept.

v0.10.0-beta

v0.10.0-beta Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 21 Oct 12:37

Hytale 0.6 (Update 6) compatibility (verified against HytaleServer 0.6.8), Hytale account link, the network mod, and a full injection-hardening pass across API, daemon, web and installer.

Added

  • Per-server launch flags in the panel (Settings → Launch Settings): --accept-early-plugins, --allow-op, --disable-sentry. Allowlisted in the API and again in the daemon. Migration 033.
  • RAM limit editable in the panel (admins only, 512 MB up to the node's total).
  • GET /api/v1/hytale/versions: newest server build per patchline, read from maven.hytale.com. The create-server form now offers Release / Pre-release instead of a free-text version.
  • Network mod (mods/talepanel-network): Hytale plugin with /play <gamemode> on hubs (signed referToServer handoff) and a referral gate on require_referral gamemodes. Builds against com.hypixel.hytale:Server:0.6.8. The config now lives at {server}/talepanel/network.json instead of inside mods/, which Hytale mistook for an asset pack.
  • Hytale account link (Admin → Integrations → Hytale Account): sign in once with the OAuth device flow and each opted-in server start gets its own game session, so servers boot authenticated without /auth login. Admins enable it per server (Settings → Launch Settings, migration 035), because every plugin on a server can read its session. The refresh token is stored encrypted and rotated safely; tokens reach the server via environment variables.

Changed

  • Daemon sets HYTALE_DISABLE_UPDATES and explains exit codes 8 (self-update staged) and 11 (data inside the launcher install folder).
  • Daemon provides a persistent machine-id so Hytale's encrypted auth store (auth.enc) works in containers.
  • Dependencies: Go 1.26, gin 1.12, pgx 5.11; Rust 1.98 builder; Nuxt 4.5 (Pinia 3, VueUse 14, @lucide/vue), Node 22.
  • CI: daemon passes cargo clippy -D warnings again (dead code removed); web runs nuxt typecheck (0 errors).

Fixed

  • Whitelist toggle now sends whitelist add/remove (Hytale 0.6 moved the whitelist to the hytale.server.join permission).
  • Kick no longer appends a reason, which Hytale rejects; the reason stays in the audit log.
  • Default commands: give uses --quantity, weather uses Zone1_Sunny --world {world} (there is no clear weather). Migration 032.
  • Default game commands were listed twice, and the global copy failed with "command not found".
  • Invalid server settings return 400 instead of 500.
  • Daemon logs reach stdout again: the bootstrap log subscriber blocked the configured one, so only errors were printed.
  • /play reports a gamemode as unavailable instead of throwing on a bad address or empty secret.

Security

  • Game-command parameters containing control characters are rejected; a newline smuggled a second console command past min_role.
  • DELETE /servers/:id/game-commands/:cmdId only deletes that server's own commands. Before, it could delete any server's commands and the global defaults.
  • Game-command parameters other than message/reason must be a single word without a leading --, so they cannot append arguments or flags.
  • Global built-in commands get the same min_role as the per-server defaults (they were user, so any console user could run stop/op/give). Migration 034.
  • Hytale game sessions are minted at most once per server every 10 s, and each mint is logged with the node.
  • Game server processes no longer inherit the daemon's environment secrets (TALEDAEMON_NODE_TOKEN etc.), which any plugin could read.
  • The web panel keeps the access token in memory only (it was in localStorage); a reload restores the session from the httpOnly refresh cookie.
  • The Hytale device-login link is only rendered if it is https://.
  • Network handoff tickets use a per-server key derived from the master secret (mod config version 2). A gamemode's network.json no longer holds a secret that is valid for every other gamemode. The hub still holds its gamemodes' keys, so give the hub role only to a trusted server. Upgrade: update the mod on all networked servers; the API rewrites their configs on start.
  • --allow-op can only be added or removed by admins.
  • Refresh tokens get a 30 s grace period after rotation, so parallel tabs or a reload during a refresh no longer log the user out.

Security — injection hardening

API:

  • Alert webhooks:
    • Must be https on port 443 and point to a public host.
    • Calls go through a client that refuses private addresses after DNS (no rebinding), ignores proxies and never follows redirects.
    • Webhook URLs are no longer logged.
  • Alert rules are scoped:
    • Non-admins can only create rules for servers they can view.
    • Global and node-level rules (CPU/RAM/disk, node offline, DDoS) are admin-only.
    • Events can only be resolved by their owner.
  • Audit log:
    • The client IP comes from the trusted proxy chain, not a raw header.
    • NUL bytes and invalid UTF-8 are stripped, and secrets are redacted at any depth.
    • A failed insert is retried instead of being dropped.
  • Server migration is admin-only and checks that the target node is online and has room.
  • Admins can no longer demote, disable or delete owners, and the last owner cannot be removed.
  • Request bodies are limited per route: 1 MiB by default, with larger limits for daemon callbacks, file edits and mod uploads.
  • Daemon client:
    • URLs are built with proper escaping.
    • Node addresses (fqdn, public address, port) are validated on register, enrollment and update.
    • Download filenames are encoded safely.
    • The client pool is now mutex-guarded (concurrent map access).
  • Console commands containing any control character, including line breaks, are rejected for every caller.
  • Game-command templates are substituted in a single pass. World names must match [A-Za-z0-9_-]{1,64}.
  • Player names must match [A-Za-z0-9_]{1,32} before they reach a console command (kick, ban, op, mute, network unban).
  • Mod install URLs must be https. Non-admins are limited to the CurseForge CDN.
  • MariaDB databases:
    • Names are derived from the server id (tp_<hex>), so they cannot collide.
    • DDL values are checked strictly, and SQL text no longer appears in error messages.
  • Log pushes are capped at 5000 lines and inserted in chunks.

Daemon:

  • File operations:
    • Every file operation stays inside the server directory and never follows a symlink planted by a tenant.
    • Config writes are atomic.
    • Commands are bound to {servers_dir}/{server_id}.
  • Mod downloads:
    • Only public addresses on https/443.
    • The address is pinned per hop, redirects are re-validated, and proxies are ignored.
    • Downloads are capped at 512 MiB and streamed to a temp file.
  • Archive extraction:
    • Limited to 200k entries / 20 GiB.
    • Symlinks are skipped.
    • The downloader only extracts its own archive.
  • Node token comparison is constant-time, and an empty token never matches.
  • Console input with control characters is rejected.
  • Offline Hytale binaries are copied per server instead of hardlinked, so one server cannot modify another server's jar.
  • Plugin metadata parsing reads at most 64 KiB.

Web and installer:

  • The panel sends CSP, X-Frame-Options: DENY, nosniff, Referrer-Policy and Permissions-Policy on every page.
  • External links taken from CurseForge or GitHub data must be https.
  • The device-login prompt only reads log lines written by the server during installation, so a chat message cannot inject a phishing link.
  • The alerts page only offers rule types the user's role may create.
  • install.sh and common.sh:
    • Domains, URLs, ports, UUIDs and tokens are validated.
    • Env files are written without sed.
    • JSON is built with jq.
    • The login password goes over stdin instead of argv.