Skip to content

Changelog โ€‹

All notable changes to SkySend are documented here.

v2.11.3 - Dependency Updates and Bug Fixes โ€‹

Released: June 21, 2026

๐Ÿ› Bug Fixes โ€‹

  • server: Fixed intermittent 500/502 errors for static assets behind a reverse proxy (e.g. Traefik) after a deployment by keeping server connections alive longer than the proxy's idle timeout, so the proxy no longer reuses a closed connection.

๐Ÿ”’ Security โ€‹

  • server: Updated hono to 4.12.26 to patch CORS credential reflection, IP restriction bypass, cookie injection, JWT scheme bypass, path traversal in serve-static, and AWS Lambda body-limit bypass (GHSA-88fw-hqm2-52qc, GHSA-xrhx-7g5j-rcj5, GHSA-3hrh-pfw6-9m5x, GHSA-f577-qrjj-4474, GHSA-2gcr-mfcq-wcc3, GHSA-wwfh-h76j-fc44, GHSA-rv63-4mwf-qqc2, GHSA-j6c9-x7qj-28xf, GHSA-wgpf-jwqj-8h8p).
  • web: Updated vite to 8.0.16 to fix server.fs.deny bypass and NTLMv2 hash disclosure on Windows (GHSA-fx2h-pf6j-xcff).
  • web: Updated dompurify to 3.4.11 to fix multiple XSS and attribute-pollution vulnerabilities (GHSA-hpcv-96wg-7vj8, GHSA-r47g-fvhr-h676, GHSA-rp9w-3fw7-7cwq, GHSA-76mc-f452-cxcm, GHSA-gvmj-g25r-r7wr, GHSA-vxr8-fq34-vvx9, GHSA-cmwh-pvxp-8882).
  • infra: Added pnpm overrides for ws (>=8.21.0), miniflare>undici (>=7.28.0), tsx>esbuild and wrangler>esbuild (>=0.28.1), @babel/core (>=7.29.6), and updated the vitepress>vite override to >=6.4.3 <7 to address transitive advisories in dev dependencies (GHSA-96hv-2xvq-fx4p, GHSA-58qx-3vcg-4xpx, GHSA-vmh5-mc38-953g, GHSA-hm92-r4w5-c3mj, GHSA-vxpw-j846-p89q, GHSA-pr7r-676h-xcf6, GHSA-p88m-4jfj-68fv, GHSA-35p6-xmwp-9g52, GHSA-g8m3-5g58-fq7m, GHSA-g7r4-m6w7-qqqr, GHSA-4x5r-pxfx-6jf8, GHSA-fx2h-pf6j-xcff).
  • server: Updated @hono/node-server to 2.0.5 to patch a serve-static middleware path-prefix bypass on Windows.

๐Ÿ”ง CI/CD โ€‹

  • infra: Bumped patch-level dependencies across the monorepo (radix-ui components, react, react-i18next, idb-keyval, tailwindcss, vue, vitest, tsx, prettier, and related type definitions). Updated i18next to 26.3.1 to satisfy the updated react-i18next peer requirement.
  • infra: Bumped minor-level dependencies across the monorepo (AWS SDK v3, react-router-dom, radix-ui react-select/slot/switch, lucide-react, better-sqlite3, ink, eslint, typescript-eslint, wrangler, @cloudflare/workers-types).
  • infra: Updated commander to v15, @types/node to v26, @tailwindcss/typography to 0.5.20, and fflate to 0.8.3.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.11.3
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.11.2 - Cache-Control Fiexes & View Count Bug Fix โ€‹

Released: June 5, 2026

๐Ÿ› Bug Fixes โ€‹

  • server: The view count returned after opening a note now reflects the authoritative stored value, and notes that have reached their view limit are handled correctly. (#59)

๐ŸŽจ Improvements โ€‹

  • server: Added Cache-Control headers so proxies no longer cache transient server errors, while content-hashed assets are served with long-term immutable caching.

๐Ÿ”ง CI/CD โ€‹

  • infra: Added typecheck scripts to every TypeScript package so pnpm validate and CI now type-check the entire monorepo, not just the web app, preventing type errors from slipping through to the Docker build.
  • infra: The typecheck task now builds its workspace library dependencies first, so type checking resolves cross-package types from source and passes in a clean checkout instead of relying on previously built output.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.11.2
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.11.1 - Adaptive ZIP Compression & Packing Events in Debug Info Panel โ€‹

Released: May 31, 2026

๐ŸŽจ Improvements โ€‹

  • web: ZIP packing now uses store-only compression (level: 0) for already-compressed formats (audio, video, images, archives, and office documents), reducing CPU load on mobile devices without affecting ZIP output size.
  • client: Same adaptive compression as the web app - the CLI and TUI now also apply store-only mode for pre-compressed formats when packing multiple files.
  • web: The Technical Info timeline now shows packing events for multi-file uploads - "Packing started" when the ZIP phase begins and "Packing complete ยท ร˜ X MB/s" with the average throughput when it finishes.

๐Ÿงช Tests โ€‹

  • server: Brought routes/note.ts to 100% coverage.
  • web: Brought useUpload and useUploadHistory to 100% coverage.
  • client: Brought lib/config.ts to 100% coverage.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.11.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.11.0 - Password Protection Algorithm Removal, New Copy Button for Password Values, and Improvements โ€‹

Released: May 30, 2026

โš ๏ธ Breaking: Password-protected uploads created with PBKDF2 (prior to v2.4.0) or the legacy Argon2id parameters (v2.4.0 - v2.5.0, 4-day window) can no longer be decrypted - both algorithms have been fully removed from the decryption pipeline. All such uploads have exceeded their maximum retention period and have expired, but any password-protected file from those eras cannot be opened after upgrading to this version.

โœจ Features โ€‹

  • web: Added a copy button to the password value fields in the "password" tab, matching the behaviour of the "password protection" input.

๐ŸŽจ Improvements โ€‹

  • web: Fixed the password generator not closing after clicking "generate" in the "password" tab.

๐Ÿ—‘๏ธ Removed โ€‹

  • crypto: Removed PBKDF2-SHA256 decryption support - deriveKeyFromPasswordPbkdf2 and PBKDF2_ITERATIONS are deleted, deriveKeyFromPassword now requires an Argon2id function and no longer accepts undefined as a fallback. All pre-v2.5.0 PBKDF2-protected uploads have expired.
  • web: Removed "pbkdf2" from the passwordAlgo Zod enum in the download and note-info API schemas - responses containing this value are now treated as invalid.
  • client: Removed "pbkdf2" from the passwordAlgo Zod enum in the file-info and note-info API schemas, and removed the PBKDF2 decryption branch from prepareDownload.
  • server: Removed "pbkdf2" from the accepted passwordAlgo upload header values - any upload attempt with this algorithm now returns HTTP 400.
  • crypto: Removed ARGON2_PARAMS_LEGACY (19 MiB / 2 iterations) and the argon2Params optional parameter from deriveKeyFromPassword - the return type is now the literal "argon2id-v2". All uploads created during the 4-day "argon2id" window (v2.4.0 - v2.5.0) have expired.
  • web: Removed "argon2id" from the passwordAlgo Zod enum in the download and note-info API schemas - responses with the legacy algorithm are now treated as invalid.
  • client: Removed "argon2id" from the passwordAlgo Zod enum and the legacy decryption branch in prepareDownload - the function now always uses the current Argon2id parameters.
  • server: Removed "argon2id" from the accepted passwordAlgo upload header values - new uploads with this algorithm now return HTTP 400.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.11.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.10.1 - S3 Download CORS Error Handling and Debug Info Panel Storage Backend Events โ€‹

Released: May 28, 2026

โœจ Features โ€‹

  • web: Added an isS3CorsError() pattern to showKnownErrorToast() so S3/R2 CORS failures during download are shown as an enriched toast with a Copy button and a link to the troubleshooting docs.
  • web: The Debug Info Panel event timeline now shows which storage backend is active: "S3 upload active" when the server uses S3/R2 for an upload, and "S3 presigned URL received" when a download fetches directly from S3/R2 (all three download tiers covered).

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed S3 downloads via presigned URL crashing the download page. After the switch from iframe to <a> navigation for Service Worker streaming, a CORS or network error from the S3/R2 bucket caused the browser to navigate the main page away. The Service Worker now catches those errors, signals the main thread via BroadcastChannel to fall back to the next download tier, and returns a safe attachment response to prevent page navigation.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.10.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.10.0 - New Copy & Share Features, Download UX Improvements, and Bug Fixes โ€‹

Released: May 24, 2026

โœจ Features โ€‹

  • web: Added a copy button and a password generator button to the "Password protection" input on all upload types.
  • web: Added a "View" button (eye icon) to note cards in "My Uploads" to open the share link directly in the browser.
  • web: The browser favicon now shows a circular progress indicator during active downloads and is restored once the download finishes, fails, or is cancelled.
  • web: Added a "Cancel Download" button that aborts the active download across all tiers (Service Worker, File System Access, Blob).
  • web: Added an in-app Debug Info Panel with runtime details (download tier, browser, DevTools status, file size, transport, event timeline) and a "Copy to clipboard" button.
  • web: Added a Firefox DevTools detection warning modal when DevTools are docked at download start, with a retry button and an escape-hatch to proceed anyway.
  • web: Average download speed is now shown in the download completion card (e.g. "ร˜ 85.3 MB/s"), matching the existing upload display.
  • client: Average download speed is now shown in the CLI output and TUI completion screen after a successful download.
  • web: Replaced inline error messages with a global toast notification system for upload, note, SSH key, and decryption errors.
  • web: Added a showToast() helper with optional Copy and Docs action buttons for enriched toast notifications.
  • web: Added showKnownErrorToast() that automatically enriches crypto pipeline errors (e.g. missing HTTPS) with a title, Copy button, and Docs link.
  • web: Added an isOriginNotAllowedError() pattern to showKnownErrorToast() for misconfigured ALLOWED_ORIGINS WebSocket rejections.

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed the note password input becoming permanently disabled after a wrong password attempt.
  • web: Fixed the SSH key fingerprint overflowing its container on narrow screens.
  • web: Fixed the remove button and file-size badge being pushed off-screen for files with very long names in the upload list.
  • web: Removed per-record console.debug calls from the Service Worker download pipeline that caused multi-minute Firefox UI freezes on large files.

๐ŸŽจ Improvements โ€‹

  • web: Replaced the clients.matchAll() broadcast in the Service Worker with a BroadcastChannel("skysend-download") for all SW-to-main-thread and config messages.
  • web: Increased the Service Worker ReadableStream highWaterMark from 2 to 8 to prevent brief download UI freezes on slow or jittery connections.
  • web: Added lightweight diagnostic logging to the Service Worker (stream-start summary, per-1000-record checkpoints, slow-read alerts, double-readMore() detection).

๐Ÿงช Tests โ€‹

  • web: Brought apps/web test coverage to 100% - added tests for isFirefox, isDevToolsOpen, and getBrowserInfo in utils, dismiss-all and multi-toast UPDATE in useToast, loadInfo non-ApiError path and view() without prior loadInfo in useNoteView, transport worker messages in useUpload, and 410/multi-upload branch coverage in useUploadHistory. Added /* v8 ignore next */ annotations on dead-code and unreachable branches in useUpload, useToast, and useNoteView.
  • client: Brought apps/client test coverage to 100% - added token storage tests (array JSON, corrupt JSON, clearStoredToken) to config, rejection-sampling branch test to password-generator. Added /* v8 ignore next */ annotations on dead-code branches in progress and oidc.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.10.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.9.5 - Cache-Control Fixes for Stale Content and Traefik Caching โ€‹

Released: May 20, 2026

๐ŸŽจ Improvements โ€‹

  • server: Changed Cache-Control for index.html and download-sw.js from no-cache, must-revalidate to no-store. no-cache permits storing the response and requires proxy revalidation via ETag or Last-Modified headers, which SkySend does not set - causing Traefik's caching middleware to fall back to its own TTL and serve stale HTML after a deployment. no-store is unconditional and prevents any proxy from storing the response, eliminating the need for a Traefik restart after updates.
  • server: Added a global Cache-Control: no-store middleware to all /api/* routes. Previously only the successful download stream response carried this header. Error responses from any API endpoint (e.g. a transient 500 from the download route) had no cache directive, allowing Traefik to cache them. A single cached error response caused all subsequent requests to the same URL to receive the cached error until the proxy was restarted.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.9.5
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.9.4 - Service Worker Download Fixes for Firefox & Improved Caching โ€‹

Released: May 20, 2026

๐Ÿ› Bug Fixes โ€‹

  • web: Added try/catch around both crypto.subtle.decrypt calls in the Service Worker. An unauthenticated or corrupted encrypted record caused the decrypt call to throw, which rejected the pull() promise and let Firefox mark the download as completed with the incorrect partial file size. The stream is now explicitly errored via controller.error() and a dl-error broadcast is sent to the UI on failure.
  • web: Added a cancelled flag to the Service Worker's cancel() handler, checked at every await boundary in pull(). Previously, calling cancel() while pull() was awaiting readMore() let pull() continue executing on an already-cancelled stream, which could reach controller.close() and throw.

๐ŸŽจ Improvements โ€‹

  • web: Changed the Service Worker ReadableStream from highWaterMark: 0 to highWaterMark: 2 to address reported Firefox browser freezes during large-file downloads. With highWaterMark: 0, pull() is only triggered by a pending consumer read(), which may cause Firefox's download pipeline to block until a decrypted record is ready. With highWaterMark: 2, pull() runs proactively and keeps up to two pre-decrypted records in the internal queue, reducing the chance of a synchronous stall. pull() still enqueues exactly one record per call, so the stall-at-random-percentage behavior from v2.9.2 cannot recur.
  • server: download-sw.js is now served with Cache-Control: no-cache, must-revalidate. Previously the file was served by the static file middleware with no explicit cache header, allowing browsers and intermediate proxies to apply heuristic caching. With no-cache, browsers byte-check the Service Worker file on every navigation and register any updated version immediately after a deployment, so users are never stuck running an outdated SW.
  • web: Replaced the single-buffer copy strategy in the Service Worker ECE decryption pipeline with a zero-copy chunk queue. Previously appendToBuf() copied both the leftover bytes from the previous chunk (~65 KB) and the newly received chunk (~65 KB) into a fresh combined buffer on every pull() call - generating ~5 GB of unnecessary allocations for a 2.4 GB file. The new implementation pushes incoming reader.read() chunks into a queue by reference. readFromBuf() copies only the bytes required for the current decrypt call (one record, 65552 bytes), reducing GC pressure by roughly 2.5x and eliminating the speed oscillation and browser sluggishness during large downloads.
  • web: Eliminated the per-record Uint8Array allocation in readFromBuf() by introducing a pre-allocated scratchRecord buffer (ENCRYPTED_RECORD_SIZE bytes) that is reused across all pull() calls. crypto.subtle.decrypt copies its input synchronously before returning the Promise, making the buffer safe to reuse as soon as the await resolves. This removes a further ~2.4 GB of GC-managed allocations per large file download, reducing peak heap pressure and Firefox RAM consumption.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.9.4
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.9.3 - Debugging Service Worker Download Stalling in Firefox โ€‹

Released: May 17, 2026

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed Service Worker downloads stalling at a random percentage (e.g. 0%, 13%, 21%) on Firefox with fast network connections. The pull() handler was processing all buffered ECE records in a single call, enqueuing multiple chunks at once. Firefox v128+ enforces the highWaterMark: 0 pull-based contract more strictly and loses its backpressure state when pull() enqueues more than one chunk, causing the ReadableStream to stop requesting more data mid-download. The inner loop is now replaced with a single-record-per-pull() pattern followed by an early return, which gives Firefox's download manager time to consume each chunk before the next one is produced.

๐Ÿงช Tests โ€‹

  • web: Added console.debug diagnostic logging to the Service Worker's pull() and readMore() functions.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.9.3
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.9.2 - Firefox Hotfix release & Browser Cache fix โ€‹

Released: May 17, 2026

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed Firefox hanging on Service Worker-streamed downloads for files >= 2 GiB. Firefox has a long-standing signed 32-bit integer overflow in its internal download pipeline that triggers when Content-Length is >= 2^31 bytes, causing the download manager to stall or cancel at the end. The Content-Length header is now omitted for files >= 2 GiB so Firefox falls back to reading until EOF. Files below 2 GiB and all other browsers are unaffected. Thanks @Dominion0815
  • web: Fixed the Service Worker download progress not reaching 100% and the UI not transitioning to "done" after the download completes. The dl-done broadcast was fire-and-forget - Firefox terminates the SW as soon as waitUntil resolves, abandoning the still-pending clients.matchAll() call before the message is delivered. All completion broadcasts are now awaited before streamDone() is called.

๐ŸŽจ Improvements โ€‹

  • server: The SPA entry point (index.html) is now served with Cache-Control: no-cache, must-revalidate. This prevents browsers and reverse proxies (e.g. Traefik with a caching middleware) from serving a stale index.html after a deployment. Without this, a cached old index.html referencing a previous JS bundle hash would cause 500 errors for the JS assets because the old filenames no longer exist on the new server.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.9.2
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.9.1 - Fixes for Large File Downloads in Firefox and SEO Meta Tag Improvements โ€‹

Released: May 16, 2026

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed large file downloads in Firefox being truncated at ~40-50% when using Service Worker streaming. The hidden <iframe> navigation trigger has been replaced with an <a> click (no download attribute), matching Mozilla Send's approach. Firefox was cutting the SW stream during the iframe-to-download-manager handoff, resulting in incomplete files.

๐ŸŽจ Improvements โ€‹

  • web: Updated SEO meta tags (title, description, Open Graph, Twitter Card) to mention both file and note sharing. Added og:image and twitter:image for rich link previews on Discord and other platforms. The image defaults to /logo.png and can be overridden with the VITE_OG_IMAGE environment variable at build time.
  • web: The page <title> and OG/Twitter title tags now reflect CUSTOM_TITLE at runtime. When CUSTOM_TITLE=MyShare is set, the preview title becomes "MyShare | Encrypted File & Note Transfer" instead of "SkySend | ...".
  • server: The SPA fallback route now injects CUSTOM_TITLE into the served index.html at request time (cached after first read) so link-preview scrapers see the correct title without a separate build-time variable.

๐Ÿ”„ Changed โ€‹

  • docs: The Domain has moved from skysend.ch to skysend.app. All documentation, API references, and examples have been updated to reflect the new domain. The old skysend.ch URLs will continue to work and redirect to skysend.app for the foreseeable future.
  • server: Added CUSTOM_REPORT_URL environment variable. When set, a "Report" link appears in the footer pointing to the configured URL - intended for abuse/report pages. Instance operators who do not set this variable will not show the link.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.9.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.9.0 - Multi-block Code Notes and UI Improvements โ€‹

Released: May 15, 2026

โœจ Features โ€‹

  • web: Added multi-block code notes. The Code tab now supports multiple code blocks per note, each with an optional filename/title and a language selector (Auto-detect or one of 44 supported languages). On the view page, blocks show a detected language badge and can be collapsed individually or all at once - single-block notes expand by default, multi-block notes start collapsed. (#45)

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed the password generator length input being slightly clipped for three-digit values (100+). The field width was increased from w-16 to w-20 so numbers like 106 or 128 are fully visible.
  • web: Fixed invisible burn-after-reading warning text in light mode. The warning box now uses text-destructive (colored) instead of text-destructive-foreground (white), making the text readable on the light semi-transparent red background. (#46)
  • web: Fixed syntax highlighting in code snippets for light mode. The code block now uses the GitHub light theme in light mode (#f6f8fa background) and the Arta dark theme in dark mode (#222 background), ensuring all tokens are readable in both themes. (#45)

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.9.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.8.0 - OIDC/SSO Authentication, General Improvements, Security & Dependency Patches โ€‹

Released: May 14, 2026

โœจ Features โ€‹

  • server: Added optional OIDC/SSO authentication via a plugin adapter system. Supports Generic, PocketID, Authentik, and Keycloak providers via the OIDC_PROVIDER env var. File uploads and note creation can each be independently protected using OIDC_PROTECT_FILES and OIDC_PROTECT_NOTES. Both HTTP and WebSocket upload transports are guarded. Sessions are stateless JWT cookies - no database changes required.
  • web: Added inline auth blocks on the upload page when OIDC is enabled and the user is not logged in. A user indicator with logout button is shown in the navigation header when authenticated.
  • client: Added OIDC authentication support for the CLI. When a server has OIDC_PROTECT_FILES or OIDC_PROTECT_NOTES enabled, the CLI automatically opens a browser for login before uploading or creating notes. Session tokens are stored per-server in ~/.config/skysend/tokens.json and reused until they expire. New auth subcommands (login, logout, status) allow explicit session management.

๐Ÿ”’ Security โ€‹

  • infra: Added pnpm overrides for @esbuild-kit/core-utils>esbuild (>=0.25.0) and vitepress>vite (~6.4.2) to address GHSA-67mh-4wv8-2f99 (esbuild dev server CORS bypass) and GHSA-4w7w-66w2-5vf9 (Vite path traversal in optimized deps .map handling).
  • infra: Updated all dependencies to latest versions - vite 8.0.13, tailwindcss + @tailwindcss/vite 4.3.0, better-sqlite3 12.10.0, @aws-sdk/* 3.1046.0, i18next 26.1.0, lucide-react 1.16.0, tailwind-merge 3.6.0, vitest + @vitest/coverage-v8 4.1.6, tsx 4.22.0, and others.

๐ŸŽจ Improvements โ€‹

  • web: The password input placeholder no longer says "(optional)" when FORCE_FILE_PASSWORD or FORCE_NOTE_PASSWORD is enabled - it now correctly says "(required)".
  • web: The navigation header title now truncates with an ellipsis when a custom title is very long, preventing layout overflow on all screen sizes.
  • web: Added a fade gradient at the bottom of the language switcher dropdown to indicate that the list is scrollable. The gradient disappears automatically when scrolled to the bottom.
  • web: Added a hamburger menu for mobile screens. All navigation links, the language switcher, theme toggle, and OIDC login/logout are now accessible in a collapsible dropdown on small viewports.
  • web: The language selector dropdown now has a fixed max height with a scrollable list (using shadcn ScrollArea) and a search input at the top, so all languages are accessible on small screens without getting cut off.
  • web: The logout button tooltip in the navigation header now uses the shadcn Tooltip component instead of a native browser title attribute.

๐Ÿงช Tests โ€‹

  • server: Added unit tests for the OIDC auth layer, all four provider adapters, the guard middleware, and auth routes, plus expanded coverage across multiple server modules - overall line coverage improved from 84.44% to 90%.
  • client: Added unit tests for the OIDC login flow and progress/password prompt utilities, bringing both modules to near-100% coverage.
  • web: Added unit tests for the auth hook, session API, and all remaining hooks that previously had 0% coverage.
  • server: Increased patch coverage for OIDC-related modules - added tests for verifySessionJwt/verifyPkceJwt returning null on malformed payloads, the String(err) branch in the discovery warm-up handler, and empty-claims fallback paths in all four provider adapters, bringing auth/session.ts, routes/auth.ts, and all auth/adapters/*.ts to 100% branch coverage.
  • client: Added tests for the getFreePort error path and the performOidcLogin catch block, bringing lib/oidc.ts to 100% line coverage.

๐Ÿ“ Documentation โ€‹

  • docs: Added OIDC Authentication page to the Developer Guide API Reference, covering the full PKCE login flow, auth/callback/logout/session endpoints, the OIDC guard middleware, protected vs. always-public endpoints, provider adapters, session JWT format, and the CLI device-browser login flow.
  • docs: Added OIDC/SSO to the features list on the landing page.
  • docs: Extended the API Overview with the /auth/* endpoint table and a link to the new OIDC page.
  • docs: Added auth login, auth logout, and auth status to the client CLI command reference, including the OIDC login flow explanation and token storage details.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.8.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.7.1 - Two New Languages & Markdown Rendering Fixes โ€‹

Released: May 13, 2026

โœจ Features โ€‹

  • web: Added Japanese (ja) translation. Thanks @canaria-computer (#41)
  • web: Added Brazilian Portuguese (pt-BR) translation. Thanks @magisph (#40)

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed Markdown preview and note view not rendering headings, blockquotes, lists, and other block-level elements. The @tailwindcss/typography plugin was installed but not loaded via @plugin in index.css, so prose styles had no effect. (#42)

๐Ÿ”„ Changed โ€‹

  • web: Markdown prose elements (list bullets, counters, links, blockquote borders, table borders, and horizontal rules) now follow the project's primary color, including the CUSTOM_COLOR branding setting.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.7.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.7.0 - Native OS Share Button, Security Patches, and Dependency Updates โ€‹

Released: May 8, 2026

โœจ Features โ€‹

  • web: Added a native OS Share button to the upload success screen. Uses the Web Share API (navigator.share()) and is only shown on devices that support it (iOS Safari, Android Chrome). The Copy button remains unchanged as fallback.

๐Ÿ”’ Security โ€‹

  • server: Updated hono from 4.12.15 to 4.12.18 to patch two moderate vulnerabilities - bodyLimit() bypass for chunked requests (GHSA-9vqf-7f2p-gf9v) and unvalidated JSX tag names allowing HTML injection (GHSA-69xw-7hcm-h432).

๐ŸŽจ Improvements โ€‹

  • infra: Updated all dependencies to their latest compatible versions (react 19.2.6, zod 4.4.3, react-router-dom 7.15.0, vite 8.0.11, @aws-sdk/* 3.1045.0, eslint 10.3.0, dompurify 3.4.2, and others).

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.7.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.6.0 - New Customization Options, Added Chinese Language and Bug Fixes โ€‹

Released: May 6, 2026

โœจ Features โ€‹

  • web: Added Simplified Chinese (zh-CN) translation. Thanks @Liyouran-center (#36)
  • server: Added DEFAULT_THEME env var to set the default UI theme (dark, light, or system) for users who have not stored a preference. The user's own choice always takes precedence. (#35)
  • server: Added DEFAULT_TAB env var to set the default upload tab (file, text, password, code, or sshkey). Falls back to the first enabled tab if the configured tab is unavailable. (#35)
  • server: Added FORCE_FILE_PASSWORD env var - when set to true, all file uploads must be password-protected. Enforced on both the server (HTTP 400) and in the UI. (#35)
  • server: Added FORCE_NOTE_PASSWORD env var - when set to true, all note uploads (text, password, code, SSH key) must be password-protected. Enforced on both the server (HTTP 400) and in the UI. (#35)
  • client: FORCE_FILE_PASSWORD and FORCE_NOTE_PASSWORD are now respected by the CLI client. When enforced, the CLI automatically prompts for a password if -p was not provided. The interactive TUI skips the "Password protect?" question and goes directly to the password input prompt. (#35)

๐Ÿ› Bug Fixes โ€‹

  • docker: Fixed health check failing when a custom PORT is set - the HEALTHCHECK command hardcoded port 3000 instead of reading the PORT environment variable. (#34)

๐Ÿ”„ Changed โ€‹

  • client: WebSocket upload transport is globally disabled. Large file transfers via WebSocket over HTTPS connections fail mid-transfer due to an unresolved issue. HTTP chunked upload is now always used. The per-server toggle has been removed from the settings until the root cause is fixed.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.6.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.7 - Docker Entrypoint Custom Data/Uploads Directory Fix โ€‹

Released: May 3, 2026

๐Ÿ› Bug Fixes โ€‹

  • docker: Fixed EACCES: permission denied on startup when DATA_DIR or UPLOADS_DIR are set to a custom path - the entrypoint previously hardcoded /data and /uploads for mkdir and chown, so custom paths were never created or made writable. The entrypoint now uses the actual DATA_DIR and UPLOADS_DIR environment variables.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.7
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.6 - Docker Entrypoint PGID Fix โ€‹

Released: May 3, 2026

๐Ÿ› Bug Fixes โ€‹

  • docker: Fixed container startup failing with addgroup: group 'skysend' in use when PGID is set to a value other than the default 1001 - busybox's delgroup cannot remove a group that still has members, so the subsequent addgroup always failed. The entrypoint now uses sed to update the GID in-place in /etc/group and /etc/passwd, matching the existing approach used for PUID.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.6
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.5 - CSP Fix for Password-Protected Uploads, Downloads and Notes โ€‹

Released: May 2, 2026

๐Ÿ› Bug Fixes โ€‹

  • server: Fixed password-protected file and note uploads/downloads failing with WebAssembly.compile() blocked by CSP in browsers behind reverse proxies that forward CSP headers - added 'wasm-unsafe-eval' to script-src to allow Argon2id (hash-wasm) to compile its inline WASM binary.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.5
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.4 - Content Security Policy Update for Custom Logo Support โ€‹

Released: May 1, 2026

๐Ÿ”„ Changed โ€‹

  • server: Content Security Policy now dynamically allows the origin of CUSTOM_LOGO in img-src when an external HTTP(S) logo URL is configured, while keeping the default image policy strict.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.4
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.3 - WebSocket Upload Keepalive โ€‹

Released: April 25, 2026

๐Ÿ› Bug Fixes โ€‹

  • server: Fixed WebSocket uploads hanging at 100% on remote servers behind a reverse proxy - the server now sends a keepalive message every 5 seconds during the finalization phase so Caddy/Nginx/Traefik do not close the connection as idle while the server is still flushing data to storage and writing to the DB.

๐Ÿ”ง CI/CD โ€‹

  • infra: Added branche ignore rule to stop branch-specific workflows (e.g. release.yml) from running on the main branch - these workflows are only meant to run on feature branches and tags, not on main where they cause noise and duplicate runs alongside the generic validate.yml.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.3
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.2 - Client Improvements & Bug fixes โ€‹

Released: April 25, 2026

๐Ÿ› Bug Fixes โ€‹

  • client: Fixed resolveServer() ignoring defaultServer and using the legacy top-level server field instead - if both fields exist in config.json (e.g. after migrating to multi-server), the TUI and all commands now correctly prefer defaultServer.
  • client: Fixed WebSocket uploads hanging at 100% on remote servers - the progress bar reached 100% as soon as data was queued in Node.js's send buffer, not when it arrived at the server, causing the fixed 5-minute finalize timeout to expire for large files on slow connections. The send buffer is now drained to zero before sending "finalize", the timeout is dynamic (5 min + 2 s/MB), and the TUI/CLI show "Finalizing..." while waiting for the server confirmation.

๐ŸŽจ Improvements โ€‹

  • client: TUI and non-interactive CLI now display the average upload speed on the summary screen after a successful upload, matching the existing web behavior.

๐Ÿ“ Documentation โ€‹

  • docs: Updated the benchmarks page with more specific details on the environment, new results and client tests.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.2
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.1 - Bug fixes, dependency updates, and Dockerfile improvements โ€‹

Released: April 25, 2026

๐Ÿ› Bug Fixes โ€‹

  • client: Fixed skysend update failing on Windows with "Permission denied" even as Administrator. Windows locks running .exe files, so fs.renameSync always threw EPERM. The fix spawns a detached, hidden cmd.exe batch script that waits 2 seconds (until the current process exits) then moves the downloaded binary into place with move /y.
  • client: Fixed install.ps1 hanging silently during download. PowerShell's default $ProgressPreference = 'Continue' makes Invoke-WebRequest up to 100x slower and shows no feedback in many terminal environments. The script now sets $ProgressPreference = 'SilentlyContinue' and prints Downloading <file>... done (X.X MB) and Verifying checksum... ok step messages instead.
  • client: Fixed install.sh showing no output during binary download. curl -fsSL and wget -q were fully silent. The binary download now uses curl --progress-bar (shows a ##### bar on stderr) and wget without -q, so users see download progress.
  • server: Fixed S3 uploads failing with Cloudflare R2 and other S3-compatible providers with the error [EntityReplacer] Invalid character '#' in entity name: "#xD". The root cause was fast-xml-parser@5.7.1 introducing a regression where numeric character references (e.g. &#xD;) in XML responses could no longer be parsed. Updated fast-xml-parser override to >=5.7.2 which restores correct behavior.
  • server: Set requestChecksumCalculation and responseChecksumValidation to WHEN_REQUIRED on the S3 client. AWS SDK v3 >=3.679 defaults to WHEN_SUPPORTED, causing proactive CRC checksum headers that can trigger provider-specific XML parsing issues.

๐Ÿ”’ Security โ€‹

  • infra: Added pnpm.overrides for postcss (>=8.5.10) to patch a moderate XSS vulnerability (GHSA-qx2v-qp2m-jg93) in transitive dependencies via autoprefixer

๐ŸŽจ Improvements โ€‹

  • server: Updated @hono/node-server from v1 to v2 - same public API, up to 2.3x faster body parsing via optimized direct Node.js IncomingMessage reads, URL construction fast-path, and buildOutgoingHttpHeaders optimization
  • infra: Updated patch and minor dependencies across all workspace packages - hono, @aws-sdk/client-s3, @aws-sdk/lib-storage, @aws-sdk/s3-request-presigner, better-sqlite3, tailwindcss, @tailwindcss/vite, react-router-dom, i18next, react-i18next, lucide-react, autoprefixer, vite, vue, wrangler, @cloudflare/workers-types, prettier, typescript, eslint-plugin-react-hooks, globals, typescript-eslint
  • infra: Updated eslint and @eslint/js from v9 to v10, and commander from v13 to v14 - no API changes required, fixed two new eslint:recommended rules (no-useless-assignment in upload chunking code, preserve-caught-error in upload worker)
  • web: Removed deprecated @types/dompurify - DOMPurify v3+ ships its own TypeScript declarations
  • infra: Added COPY apps/client/package.json, COPY apps/client/stubs/, and COPY workers/instances/package.json to the Dockerfile build stage so pnpm install --frozen-lockfile can resolve all workspace packages (including the file: stub dependency in @skysend/client) before COPY . .

๐Ÿ—‘๏ธ Removed โ€‹

  • server: Removed S3_PUBLIC_URL environment variable. S3 downloads now exclusively use presigned URLs, which enforce expiry and download limits server-side and expire automatically. Public bucket URLs allowed clients to bypass these controls by reusing a captured URL.

๐Ÿ“ Documentation โ€‹

  • docs: Removed PBKDF2-SHA256 fallback references from password-protection.md, README.md, and docs/index.md - password protection now exclusively documents Argon2id

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.5.0 - Security Audit Fixes, Test Coverage Improvements, and Docker Metadata Labels โ€‹

Released: April 23, 2026

โœจ Features โ€‹

  • server: Added per-IP per-resource password attempt lockout - after 10 failed attempts the IP is locked out for 15 minutes with a Retry-After header, IPs stored as ephemeral HMAC-SHA256 hashes, configurable via PASSWORD_MAX_ATTEMPTS and PASSWORD_LOCKOUT_MS

๐Ÿ”’ Security โ€‹

  • server: Updated hono from 4.12.12 to 4.12.14 to fix HTML injection via improperly handled JSX attribute names in SSR (GHSA-458j-xx4x-4375)
  • infra: Added pnpm.overrides for esbuild (>=0.25.0), vite (>=6.4.2), and fast-xml-parser (>=5.7.0) to patch transitive vulnerabilities in dev/docs dependencies (GHSA-67mh-4wv8-2f99, GHSA-4w7w-66w2-5vf9, GHSA-gh4j-gqv2-49f6)
  • crypto: Tightened Argon2id-to-PBKDF2 fallback logic - the fallback now only triggers on WASM availability errors (CompileError, LinkError, or matching message) and propagates all other crypto errors instead of silently swallowing them
  • crypto: Increased Argon2id parameters from 19 MiB / 2 iterations to 64 MiB / 3 iterations, matching OWASP's strong recommendation and significantly raising GPU brute-force cost for new password-protected uploads
  • crypto: Increased HKDF salt length from 16 to 32 bytes for new uploads, matching the RFC 5869 recommendation to use a salt equal to the hash output length - legacy 16-byte salts from existing uploads are still accepted
  • crypto: Added stream truncation detection to createDecryptStream - callers can pass expectedPlaintextSize (from authenticated metadata) to detect a malicious server delivering fewer records than were encrypted
  • server: Added Referrer-Policy: no-referrer HTTP header to prevent URL fragments from leaking via Referer header in misconfigured or future environments
  • web: Added <meta name="referrer" content="no-referrer"> to index.html as defense-in-depth for the referrer policy
  • web: URL fragment (encryption key) is now removed from the browser address bar via history.replaceState once decryption begins, preventing key leakage through browser history
  • web: Note uploads now use Argon2id for password key derivation - previously PBKDF2 was always used for notes due to a missing argument
  • crypto: Removed Argon2id-to-PBKDF2 upload fallback entirely - if Argon2id WASM fails during an upload, an error is thrown instead of silently downgrading to PBKDF2 ("fail secure"), PBKDF2 decryption for existing uploads is unaffected
  • web: Added DOMPurify sanitization of highlight.js output before dangerouslySetInnerHTML in code notes - defense-in-depth against any future upstream hljs vulnerability
  • web: Added rehype-sanitize plugin to ReactMarkdown rendering in notes - prevents XSS from future react-markdown upstream changes that could enable raw HTML
  • web: URL fragment (encryption key) is now removed from the browser address bar via history.replaceState in NoteView immediately at page mount - previously only the Download page had this protection
  • server: Fixed IP extraction when TRUST_PROXY=true - previously the leftmost (client-controlled) value from X-Forwarded-For was used, allowing clients to spoof their IP and bypass rate limiting and upload quotas, now uses the rightmost (proxy-appended) value
  • server: Fixed S3 download with S3_PUBLIC_URL configured - previously a permanent public URL was returned, remaining valid indefinitely after DB record deletion and bypassing expiry/download-limit enforcement, now always uses presigned URLs with a TTL
  • web: Replaced deprecated apple-mobile-web-app-capable meta tag with the standard mobile-web-app-capable equivalent - eliminates browser console warning, the PWA manifest display: standalone already handles standalone mode on modern browsers

๐ŸŽจ Improvements โ€‹

  • web: Password prompt now shows a translated "too many attempts" error when the server returns 429 instead of switching away from the password screen

๐Ÿ”ง CI/CD โ€‹

  • infra: Added OCI standard labels to Docker images via docker/metadata-action@v5 - sets title, description, url, source, version, revision, created, vendor, and licenses for better registry compatibility and Renovate/Dependabot integration

๐Ÿงช Tests โ€‹

  • crypto: Expanded to 129 tests with 100% coverage - added security-property tests for HKDF domain separation, ECE reorder/truncation attacks, Argon2id error propagation, PBKDF2 known-answer verification, and legacy salt backward compatibility.
  • server: Added 24 integration tests for the chunked upload flow (/init, /chunk, /finalize), password-attempt lockout (429 + Retry-After), and invalid input handling across meta.ts, password.ts, and note.ts routes.
  • server: Added 5 tests for startCleanupJob (interval, stop function, logging, error recovery) - bringing cleanup.ts to 100%.
  • server: Brought upload-validation.ts and quota.ts to 100% - covers all check(), getStatus(), 413 middleware, DB key restoration, and interval behavior (rotation, expiry cleanup).
  • infra: Added vitest.config.ts for server and client, updated vite.config.ts for web - all with scoped coverage.include and explicit excludes for untestable files (browser workers, WASM, S3 backend, app entrypoints).

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.5.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.4.3 - Codecov, Unit Test Improvements & Web Improvements โ€‹

Released: April 21, 2026

โœจ Features โ€‹

  • client: TUI "Manage servers" now supports adding, deleting, and setting a server as default via a server action sub-menu

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed note view incorrectly showing "permanently deleted" warning for unlimited-view notes (maxViews === 0)

๐Ÿงช Tests โ€‹

  • infra: Added @vitest/coverage-v8 and test:coverage scripts to server, web, crypto, and client packages for coverage report generation in LCOV format
  • web: Added 57 unit tests across lib/utils, lib/password-generator, and lib/upload-store - covering formatting functions, isSafari detection, generatePassword/calculateEntropy, and full CRUD/sorting for IndexedDB upload and note storage (using an in-memory idb-keyval mock)
  • client: Added 93 unit tests across lib/progress, lib/url, lib/password-generator, lib/config, and lib/history - covering all formatting/parsing utilities, full parseShareUrl/buildShareUrl logic including edge cases, password generation, config file lifecycle with filesystem isolation via tmpdir, and history CRUD with expiry cleanup

๐Ÿ”ง CI/CD โ€‹

  • infra: Updated validate.yml test job to run with coverage and upload reports to Codecov via codecov/codecov-action@v5
  • infra: Added codecov.yml with project and patch coverage status checks
  • crypto: Added 14 new unit tests covering previously untested security-critical paths: validateMetadata error branches (invalid JSON, null payload, unknown type, malformed archive entries, negative sizes, empty names, missing MIME type), deriveKeyFromPasswordArgon2 input validation, ECE decrypt stream "record too short" path, and exact error message matching for the nonce-missing guard. Coverage: 94% โ†’ 99.29% statements, 88% โ†’ 97.82% branches. Added vitest.config.ts to exclude the re-export barrel src/index.ts from coverage.

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.4.3
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.4.2 - WebSocket Upload Toggle and CLI History Command โ€‹

Released: April 20, 2026

โœจ Features โ€‹

  • client: Added WebSocket transport toggle - disable WebSocket uploads via --no-ws CLI flag, TUI Settings menu, or \"websocket\": false in config file- client: Added skysend ls command to list upload and note history with age, expiry, and size - supports --server, --all, and --json flags

๐ŸŽจ Improvements โ€‹

  • client: Connection error screen now offers recovery options - press s to select another server or r to retry instead of requiring Ctrl+C exit
  • client: Connection errors now show a user-friendly message (Server <url> is not reachable) instead of the raw fetch failed error
  • client: skysend config now shows all registered servers with their per-server WebSocket status

๐Ÿ“ Documentation โ€‹

  • docs: Added WebSocket transport configuration section to CLI client documentation

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.4.2
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.4.1 - Bug Fixes for CLI Binary and Client install URL Shortening โ€‹

Released: April 20, 2026

๐Ÿ› Bug Fixes โ€‹

  • client: Fixed Cannot find package 'react-devtools-core' runtime error when running compiled CLI binaries - replaced --external flag with a bundled no-op stub so Ink's optional devtools import resolves inside the binary

๐Ÿ“ Documentation โ€‹

  • docs: Shortened CLI install URLs from raw GitHub links to skysend.app/install.sh and skysend.app/install.ps1 redirects across README, docs, and install scripts

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.4.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.4.0 - CLI Client, PWA Support and ZIP creating improvements โ€‹

Released: April 19, 2026

โœจ Features โ€‹

  • web: Added PWA (Progressive Web App) support - SkySend can now be installed as an app on desktop (Chrome, Edge), Android, and iOS via "Add to Home Screen"
  • client: Added @skysend/client CLI binary for uploading and downloading files with end-to-end encryption from the terminal - supports single/multi-file uploads, encrypted notes, password protection, WebSocket and HTTP chunked transports, and cross-platform Bun-compiled binaries (Linux, macOS, Windows)
  • web: Added Argon2id password KDF support to the web frontend and upload worker using hash-wasm, enabling cross-compatibility with CLI password-protected uploads

๐Ÿ› Bug Fixes โ€‹

  • web: Fixed WebSocket upload failing through Vite dev proxy by enabling ws: true on the API proxy config

๐ŸŽจ Improvements โ€‹

  • web: Multi-file uploads now show a determinate progress bar (0-100%) during the packing phase instead of an indeterminate spinner
  • web: Multi-file ZIP creation moved from main thread into the upload worker, reducing peak memory usage by ~50% for large uploads
  • web: Average upload speed is now displayed on the share link page after upload completes

๐Ÿ”„ Changed โ€‹

  • cli: Renamed admin CLI binary from skysend to skysend-cli to avoid conflict with the new client binary (consistent with Docker and documentation)

๐Ÿ“ Documentation โ€‹

  • docs: Cleaned up docker compose example in the user guide - removed redundant comments and simplified environment variable list with a link to the full reference
  • docs: Added CLI client documentation - overview, installation guide (Linux/macOS/Windows), detailed command reference for all 7 commands (upload, download, note, note:view, delete, config, update)
  • docs: Updated README, docs homepage, getting started, installation, first steps, architecture, setup, and roadmap pages with CLI client information

๐Ÿ”ง CI/CD โ€‹

  • infra: Added CLI binary build pipeline to release workflow - compiles Bun binaries for 5 targets (linux-x64, linux-arm64, darwin-x64, darwin-arm64, windows-x64) with SHA-256 checksums and attaches them to GitHub Releases
  • infra: Added install scripts for Linux/macOS (install.sh) and Windows (install.ps1) with automatic platform detection and checksum verification

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.4.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.3.0 - WebSocket Upload Transport for Improved Performance in Proxied Environments โ€‹

Released: April 17, 2026

โœจ Features โ€‹

  • server: Added a WebSocket upload transport at /api/upload/ws that streams the encrypted payload over a single persistent connection, eliminating the HTTP/2 multiplexing bottleneck that reverse proxies (Traefik, Nginx) impose on parallel chunk uploads
  • server: Added FILE_UPLOAD_WS environment variable (default: true) to enable or disable the WebSocket upload transport
  • server: Added FILE_UPLOAD_WS_MAX_BUFFER environment variable (default: 16MB) to cap the per-session server receive buffer for WebSocket uploads
  • web: Upload worker now uses the WebSocket transport as the primary upload path and automatically falls back to the existing HTTP chunked upload when the handshake fails, is blocked, or times out (10 s)

๐Ÿ”’ Security โ€‹

  • server: Added Origin header validation on WebSocket upgrade requests to prevent cross-site WebSocket hijacking (defence-in-depth, not exploitable due to token requirements)

๐Ÿ“ Documentation โ€‹

  • docs: Added FILE_UPLOAD_WS and FILE_UPLOAD_WS_MAX_BUFFER to the user-guide environment variables page and the developer-guide environment reference
  • docs: Documented the WebSocket upload protocol in the upload API reference, including message shapes, close codes, and client fallback triggers
  • docs: Added Nginx and Traefik configuration snippets for the WebSocket upload transport in the reverse-proxy guide
  • docs: Updated developer-guide architecture to document both WebSocket (primary) and HTTP chunked (fallback) upload transports with flow diagrams

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.3.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.2.4 - Max Concurrent Chunk Uploads and Speed Limit Configuration โ€‹

Released: April 15, 2026

โœจ Features โ€‹

  • server: Added FILE_UPLOAD_CONCURRENT_CHUNKS environment variable (default: 3) to control the number of parallel chunk uploads per session - increase to improve upload speed in Chromium browsers through HTTP/2 proxies
  • server: Added FILE_UPLOAD_SPEED_LIMIT environment variable (default: 0 = unlimited) to cap upload throughput per session - supports human-readable values like 100MB (bytes per second)
  • web: Client now reads the configured concurrent chunk count from the server and adjusts parallel uploads accordingly

๐Ÿ“ Documentation โ€‹

  • docs: Added FILE_UPLOAD_CONCURRENT_CHUNKS and FILE_UPLOAD_SPEED_LIMIT to user-guide environment variables page with new "Upload Performance" section
  • docs: Added FILE_UPLOAD_CONCURRENT_CHUNKS and FILE_UPLOAD_SPEED_LIMIT to developer-guide environment reference

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.2.4
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.2.3 - Critical Bug Fixes for Chunked Uploads in HTTP/2 Proxied Environments โ€‹

Released: April 15, 2026

  • server: Fixed rate limiter path matching - the regex anchor (^) prevented chunk requests from being recognized through the /api sub-router, causing 429 errors despite the exemption
  • server: Fixed HTTP/2 flow-control deadlock that caused uploads to stall at 0-1% in Chrome, Firefox, Brave, and Edge through reverse proxies - the server now reads each chunk body immediately instead of deferring reads in a promise chain, preventing proxy flow-control backpressure from blocking the connection

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.2.3
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.2.2 - Bug Fixes for Chunked Uploads in Brave and Edge โ€‹

Released: April 15, 2026

๐Ÿ› Bug Fixes โ€‹

  • server: Chunk upload requests (/upload/:id/chunk) are now exempt from the global rate limiter - previously, uploading a large file would exceed the 60 requests/minute limit and cause 429 errors, breaking uploads entirely in production
  • web: Chunk upload body changed from Blob to ArrayBuffer - fixes uploads permanently stalling at 0% in Brave and Edge, where the browser opened HTTP/2 streams but never sent DATA frames for Blob bodies from Web Workers

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.2.2
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.2.1 - Parallel Chunk Uploads and Performance Improvements โ€‹

Released: April 15, 2026

๐ŸŽจ Improvements โ€‹

  • web: Upload chunks are now sent in parallel (up to 3 concurrent, 10 MB each) instead of sequentially (50 MB each), dramatically improving upload speed in Chrome, Brave, and Edge through reverse proxies like Traefik
  • server: Chunk upload endpoint accepts an index query parameter and reassembles chunks in-order on the server, ensuring data integrity with parallel client uploads
  • server: In-order chunks are now streamed directly to storage without buffering, eliminating unnecessary memory copies on the hot path
  • server: Optimized S3 multipart upload buffering to avoid full-buffer reallocation on every chunk append
  • server: S3 part uploads now run as a concurrent pool with smooth backpressure - waits for one upload slot to free up instead of draining everything, giving consistent throughput instead of burst-stop cycles

๐Ÿ“ Documentation โ€‹

  • docs: Updated architecture diagram with chunked upload flow (init, parallel chunks with index, finalize)
  • docs: Added chunked upload API documentation (init, chunk, finalize endpoints) to developer guide
  • docs: Added chunked upload endpoints to API overview table

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.2.1
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.2.0 - S3 Storage Backend โ€‹

Released: April 15, 2026

โœจ Features โ€‹

  • server: Added S3-compatible storage backend as alternative to local filesystem storage
  • server: Added STORAGE_BACKEND environment variable to switch between filesystem (default) and s3 storage
  • server: Added S3 configuration via environment variables (S3_BUCKET, S3_REGION, S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_FORCE_PATH_STYLE, S3_PRESIGNED_EXPIRY, S3_PUBLIC_URL)
  • server: Uploads in S3 mode stream directly to S3 via multipart upload without disk buffering on the server
  • server: Added S3_PUBLIC_URL for direct download URLs via R2 custom domains or public buckets - avoids presigned URL complexity and CORS issues
  • server: Falls back to presigned URLs when S3_PUBLIC_URL is not set (for private buckets)
  • web: Client download logic transparently handles both direct file streams (filesystem), presigned URL redirects (S3 private), and public URL redirects (S3 public)
  • server: Supports all S3-compatible providers (AWS S3, Cloudflare R2, Hetzner Object Storage, MinIO, Wasabi, Backblaze B2, DigitalOcean Spaces, and more) via custom endpoint configuration
  • server: Logs storage mode on startup (filesystem path or S3 endpoint with public/presigned mode)
  • server: S3 connectivity test on startup - verifies bucket access, write, and delete permissions before accepting requests
  • server: Added S3_PART_SIZE and S3_CONCURRENCY environment variables for tuning S3 upload throughput
  • web: Download progress bar now shows real-time download speed (e.g. 42.5 MB/s) alongside the percentage, matching the upload speed display

๐Ÿ› Bug Fixes โ€‹

  • docker: Fixed Docker healthcheck showing unhealthy despite a running server - replaced wget (not available in Alpine) with Node.js fetch and increased start period to 30s
  • web: Upload progress bar now reflects actual end-to-end upload progress instead of encryption speed - progress updates after each chunk is fully uploaded (including server-to-S3 forwarding)

๐Ÿ”’ Security โ€‹

  • server: CSP connect-src header is dynamically extended to allow client fetches to the configured S3 endpoint

๐ŸŽจ Improvements โ€‹

  • server: Introduced StorageBackend interface with adapter pattern for pluggable storage implementations
  • server: Optimized S3 multipart upload performance - configurable part size (default 25MB) and parallel part uploads (default 4 concurrent) to reduce round-trip overhead

๐Ÿ“ Documentation โ€‹

  • docs: Added S3 storage backend section to environment variables reference with configuration table, S3_PUBLIC_URL, and provider examples (R2, MinIO)
  • docs: Added S3 variable definitions to developer environment reference (STORAGE_BACKEND, S3_BUCKET, S3_REGION, S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_FORCE_PATH_STYLE, S3_PRESIGNED_EXPIRY, S3_PUBLIC_URL, S3_PART_SIZE, S3_CONCURRENCY)
  • docs: Updated architecture diagram and data storage section to reflect S3 backend and download flow
  • docs: Added S3 CORS configuration guide with examples for Cloudflare R2, AWS S3, and MinIO
  • docs: Added S3 Docker Compose example with S3_PUBLIC_URL to self-hosting guide
  • docs: Updated data backups guide with S3 storage note
  • docs: Added S3 storage mention to README and docs homepage feature cards

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.2.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.1.0 - General UI and Documentation Improvements โ€‹

Released: April 14, 2026

โœจ Features โ€‹

  • docs: Added VitePress sitemap generation (/sitemap.xml) for Google Search Console indexing
  • docs: Added Cloudflare Worker that fetches instance data (version, config, enabled services) hourly and caches it in KV
  • docs: Instances page now loads all data from a single cached API endpoint instead of querying each instance individually
  • docs: Instance limits (max file size, quota, expiry, downloads) are now fetched dynamically from each instance's /api/config endpoint
  • docs: Added service filter (All / Files / Notes) to instances page based on each instance's enabledServices configuration
  • docs: Added skeleton loading animation while instance data is being fetched
  • docs: Instance list is now maintained via docs/public/instances.json - users can add instances via pull request
  • docs: Instance cards show separate Files and Notes stats sections, each only visible when the service is enabled
  • docs: Instance cards show "Official" or "Community" badge, with official instances (skysend.app) always sorted first
  • web: Added language switcher dropdown in the navbar with country flag icons via flag-icons library
  • web: Manual language selection is persisted in a cookie so it survives page reloads and sessions
  • web: Added optional custom labels for password notes so users can describe what each password is for

๐ŸŽจ Improvements โ€‹

  • web: Redesigned theme toggle from a cycling button to a dropdown menu with Auto, Light, and Dark options
  • web: Fixed an UI issue on text and markdown note cards, when they were expanded

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.1.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v2.0.0 - Encrypted Notes, Text, Passwords, Code Snippets, and SSH Keys โ€‹

Released: April 13, 2026

โš ๏ธ Breaking: All file-related environment variables have been renamed with a FILE_ prefix (e.g. MAX_FILE_SIZE -> FILE_MAX_SIZE). Old names are no longer supported. See the environment reference for the full mapping.

โœจ Features โ€‹

  • server: Added encrypted notes API with support for text, password, and code content types
  • server: Added burn-after-reading support for notes via configurable max view count
  • server: Added new NOTE_ environment variables for independent note configuration (NOTE_MAX_SIZE, NOTE_EXPIRE_OPTIONS_SEC, NOTE_DEFAULT_EXPIRE_SEC, NOTE_VIEW_OPTIONS, NOTE_DEFAULT_VIEWS)
  • crypto: Added encryptNoteContent and decryptNoteContent for AES-256-GCM note encryption
  • web: Added tab navigation on upload page (File, Text, Password, Code)
  • web: Added note creation form with content editor, expiry, view limits, and password protection
  • web: Added IndexedDB storage for created notes
  • web: Added note view page with decryption, password prompt, view counter, and burn-after-reading indicator
  • web: Added note API client functions for fetching note info, viewing content, and password verification
  • web: Added My Uploads page filter tabs (All, Files, Text, Passwords, Code, Markdown, SSH Keys) with combined chronological list
  • web: Added note cards in My Uploads with view counter, expiry, QR code, copy link, and delete
  • server: Added ENABLED_SERVICES environment variable to enable/disable file and note services independently
  • web: Upload page and My Uploads page dynamically hide tabs for disabled services
  • server: Added unlimited views option (maxViews: 0) for notes - notes expire only by time, not by view count
  • web: View selector shows "Unlimited" option when 0 is included in NOTE_VIEW_OPTIONS
  • web: Added translations for Spanish, French, Finnish, Swedish, Norwegian, Dutch, Italian, and Polish
  • web: Added syntax highlighting with line numbers for code notes (auto-detects 22 languages)
  • web: Added password generator in the Password tab with configurable length, character types, and entropy display
  • web: Added SSH Key tab with Generate/Paste modes, Ed25519 and RSA (1024/2048/4096) key pair generation, optional passphrase (PKCS#8), and sharing as encrypted note
  • web: Added Markdown mode in Text tab with Plain Text/Markdown sub-toggle, live preview, and rendered Markdown display on note view (GFM support via react-markdown)
  • crypto: Added sshkey as dedicated NoteContentType so SSH key notes display with their own icon and label in My Uploads
  • web: Redesigned Password tab with single-line input fields, per-field password generator toggle, and add/remove support for multiple passwords
  • web: Password note viewer now shows each password individually with separate reveal and copy buttons
  • cli: Added notes support to list, delete, stats, and cleanup commands

๐Ÿ”„ Changed โ€‹

  • server: Renamed all file-related environment variables with FILE_ prefix for clarity
  • server: Cleanup job now also removes expired notes and notes that reached their view limit
  • web: File download URLs changed from /d/:id to /file/:id with automatic redirect from old URLs

๐ŸŽจ Improvements โ€‹

  • web: Replaced default browser scrollbar with custom styled scrollbar on textareas and code blocks
  • web: Updated footer tagline and browser tab subtitle to reflect file and note sharing
  • web: Removed primary-color border from ShareLink card and NoteView card to avoid confusion with custom color themes
  • web: Added success Tailwind color variable (fixed SkySend green) for the "Upload complete" text so it stays green regardless of custom primary color

๐Ÿ“ Documentation โ€‹

  • docs: Updated environment variables reference with new FILE_ and NOTE_ variable names
  • docs: Added v1 to v2 environment variable migration table to environment reference
  • docs: Updated URL references from /d/ to /file/ in architecture and API docs
  • docs: Added comprehensive API documentation for all 5 note endpoints
  • docs: Updated API index with note endpoints overview table
  • docs: Updated user guide with note creation, viewing, and burn-after-reading instructions
  • docs: Updated README, PHILOSOPHY, and docs landing page branding to reflect file and note sharing
  • docs: Added screenshots page with overview, note types, and My Uploads views

๐Ÿงช Tests โ€‹

  • crypto: Added 9 tests for note content encryption/decryption (round-trip, unicode, tampering, nonce uniqueness)
  • server: Added 33 tests for note API routes (CRUD, view counting, burn-after-reading, auth tokens, password verification, size/expiry/view validation)
  • server: Added 4 cleanup tests for note expiry and view limit enforcement
  • server: Added 7 config tests for ENABLED_SERVICES parsing, validation, and cross-field skip logic
  • server: Added 7 route tests for service guard middleware (403 on disabled services)
  • server: Added 3 tests for unlimited views (creation, viewing, cleanup skip)

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v2.0.0
  • Also tagged as: latest, v2
  • Platforms: linux/amd64, linux/arm64

v1.0.2 - Patch Release for CORS correction on Health Endpoint โ€‹

Released: April 13, 2026

๐Ÿ› Bug Fixes โ€‹

  • server: Added open CORS policy (*) on /api/health endpoint so external sites can fetch instance status

๐Ÿ“ Documentation โ€‹

  • docs: Added website and instances links to README navigation bar

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v1.0.2
  • Also tagged as: latest, v1
  • Platforms: linux/amd64, linux/arm64

v1.0.1 - Patch Release for Docker Permissions Issue โ€‹

Released: April 12, 2026

๐Ÿ› Bug Fixes โ€‹

  • docker: Replaced recursive chown on /uploads with a non-recursive, fault-tolerant call to prevent startup failures on NFS mounts and read-only filesystems

โœจ Features โ€‹

  • docker: Added SKIP_CHOWN environment variable to skip ownership changes on /data and /uploads entirely

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v1.0.1
  • Also tagged as: latest, v1
  • Platforms: linux/amd64, linux/arm64

v1.0.0 - First Stable Release โ€‹

Released: April 12, 2026

This is the first stable release of SkySend, marking the completion of the initial development phase and the beginning of production use. The v1.0.0 release includes all core features, security measures, and documentation necessary for self-hosting and public deployment.

โœจ Features โ€‹

  • crypto: AES-256-GCM streaming encryption and decryption with 64KB record size
  • crypto: HKDF-SHA256 key derivation with domain-separated keys (fileKey, metaKey, authKey)
  • crypto: Metadata encryption with random IV for filenames, MIME types, and file lists
  • crypto: Password protection via Argon2id (WASM) with PBKDF2-SHA256 fallback
  • crypto: Base64url encoding, constant-time comparison, and utility functions
  • server: Hono-based REST API with streaming upload and download
  • server: Chunked upload flow with init, stream, and finalize endpoints
  • server: SQLite database with Drizzle ORM and WAL mode
  • server: Filesystem storage layer with path traversal protection
  • server: Auth middleware with constant-time token comparison
  • server: Sliding-window rate limiting per IP with X-RateLimit-* response headers
  • server: Upload quota with HMAC-SHA256 hashed IPs and daily rotating keys for privacy
  • server: Quota status endpoint (GET /api/quota) with remaining bytes and reset time
  • server: Health check endpoint (GET /api/health) with version and timestamp
  • server: Automatic cleanup job for expired uploads on startup and at configurable intervals
  • server: Static SPA serving from Vite build output
  • server: Graceful shutdown with 10-second timeout
  • server: Configurable branding via environment variables (title, color, logo, footer links)
  • web: React 19 SPA with Vite, Tailwind CSS, and shadcn/ui components
  • web: Drag-and-drop upload zone supporting files and folders
  • web: Multi-file upload with client-side zip compression (fflate)
  • web: Three-tier download strategy - Service Worker streaming, File System Access API, and in-memory blob fallback
  • web: OPFS-backed decryption pipeline via Web Worker for zero-RAM streaming downloads
  • web: Safari warning for large file downloads exceeding 256 MB
  • web: Configurable expiry time and download limits per upload
  • web: Optional password protection with show/hide toggle
  • web: Upload progress with phase indicator, percentage, and speed display
  • web: Favicon progress circle during active uploads
  • web: Share link page with one-click copy
  • web: Upload history dashboard backed by IndexedDB - no account required
  • web: Download page with metadata decryption, password prompt, and progress
  • web: Quota bar with visual progress indicator
  • web: Skeleton loading states for all pages
  • web: Version number displayed in footer from package.json
  • web: Dark mode with automatic system preference detection
  • web: Internationalization (English, German) with browser language auto-detection
  • web: Responsive design for mobile and desktop
  • web: Toast notification system for success, error, and warning messages
  • cli: list command to show active uploads
  • cli: delete command to remove an upload by ID
  • cli: stats command for storage overview
  • cli: cleanup command to remove expired uploads
  • cli: config command to display server configuration
  • docs: Full documentation site with VitePress
  • docs: Developer guide covering architecture, API reference, crypto internals, and download modes
  • docs: User guide with installation, configuration, security, and self-hosting sections
  • infra: Multi-stage Dockerfile based on Node 24 Alpine
  • infra: Docker Compose with volume persistence and health checks
  • infra: pnpm monorepo with workspaces
  • infra: ESLint and Prettier configuration
  • infra: TypeScript strict mode across all packages
  • infra: Vitest test suite with unit and integration tests

๐Ÿณ Docker โ€‹

  • Image: skyfay/skysend:v1.0.0
  • Also tagged as: latest, v1
  • Platforms: linux/amd64, linux/arm64