Mikesoft TeamVault Changelog Entries are ordered newest first. Release dates are included where recorded. ## 3.2.6 - 2026-08-08 - Security: upload destinations now pass through the shared storage-boundary and intermediate-symlink verifier before any destination stream is opened. - Reliability: ZIP exports check directory, file, and finalization results, clean up on any throwable failure, and bound recursive traversal when corrupt folder metadata contains a cycle. - Governance: REST boolean strings are normalized with WordPress semantics, and group updates reject names that become empty after sanitization. - Multisite: new-site initialization runs only when TeamVault is active network-wide, preventing site-local activation from provisioning unrelated sites. - Admin UI: the details panel becomes an off-canvas drawer at 1360px so the WordPress desktop admin menu cannot make it cover Upload or other toolbar actions. - Repository: the GitHub README now leads with the product, installation, security, and visual proof; repository metadata, dependency automation, citation data, and vulnerability-reporting guidance were refreshed. - Tests: added regression coverage for verified upload paths, governance normalization, multisite activation scope, corrupt export cycles, and the responsive details-panel threshold. ## 3.2.5 - 2026-08-02 - Security: the file details panel escapes the stored file extension before HTML interpolation. The value is already constrained to `[a-z0-9]` by upload and reindex validation, so this is defense in depth rather than a fixed exploit; it closes the last unescaped server-derived value in the admin JavaScript after the 3.2.4 output-encoding pass. - Release metadata: aligned the plugin header, stable tag, localized repository documentation, WordPress.org changelog and upgrade notice with the real release date. - Tests: added regression coverage for the file-extension output boundary and release metadata consistency. ## 3.2.4 - 2026-08-01 - Security: private downloads, previews, and ZIP exports now retain WordPress no-cache headers; file-stream diagnostics identify records without disclosing absolute storage paths. - Security: browser preview, download, export, and audit destinations are restricted to same-origin HTTP(S) URLs, user-derived avatar text is escaped, and the interface-language setting uses the supported-language allowlist. - Performance: repeated permission checks now reuse request-scoped group membership, folder-rule, and parent-folder lookups. - Release tooling: CI actions are pinned to immutable commits, Composer dependency auditing and JavaScript syntax checks run automatically, and runtime packaging excludes local environment files, credentials, caches, coverage, Node dependencies, and generated archives. - Documentation: expanded configuration, usage, development, build, deployment, security-review, and AI-agent guidance. - Tests: added regression coverage for private response caching, path-safe diagnostics, URL handling, settings validation, and permission-query caching. ## 3.2.3 - 2026-07-18 - Security: upload validation now requires the detected MIME signature to match the file extension, inline preview requires the same explicit extension/MIME pair, and active markup MIME types are rejected. - Security: admin HTML escaping now covers quoted attribute delimiters, audit CSV exports neutralize spreadsheet formulas, and restricted folder names are omitted from exports and breadcrumbs. - Reliability: permission and group membership replacement is transactional; file and folder operations verify every metadata write and compensate reversible filesystem changes when persistence fails. - Reliability: quota-enabled uploads stop when the advisory lock cannot be acquired, file moves never overwrite an existing destination, and explicitly shared descendants remain discoverable when their parent is hidden. - Release tooling: `FreshCheckout` validates the canonical SVN working-copy path and rejects links before removal, release versions are validated before becoming tag paths, the deploy script relies on SVN prompt or credential-store authentication instead of accepting passwords, and historical generated directories are documented as non-release inputs. - Fix: new installations once again persist the documented `auto` interface-language default. - Metadata: the WordPress plugin list now displays the author as `Mikesoft`. - Tests: added regression coverage for MIME matching, contextual escaping, permission transactions, filesystem compensation, export redaction, shared descendants, quota locking, CSV output, and release path guards. ## 3.2.2 - 2026-07-07 - Improvement: file-type icons. `getFileIconSvg()` in `admin-app-core.js` now renders recognizable, brand-coloured document badges with the format label (PDF, DOC, XLS, PPT, CSV, TXT, ZIP, AUD, VID, IMG, code, FILE) instead of monochrome line glyphs, and adds the previously missing PowerPoint, audio, video, text, csv, and code types (which fell back to the generic document icon). The badges are self-coloured SVG, so they render consistently in the file grid, the list view, and the details-panel preview. ## 3.2.1 - 2026-07-06 - Fix: the empty-state action buttons ("Browse files" / "New folder") inherited the empty-state placeholder icon styling (`margin-bottom: 20px` and `opacity: 0.5`) via a descendant selector, which pushed their icons above the text baseline and dimmed them. Scoped that styling to the direct-child placeholder icon (`.pdm-empty-state > svg`) so the button icons stay vertically centered with their labels at full opacity. ## 3.2.0 - 2026-07-06 - Feature: governance visibility. Folders that carry explicit permission rules are now badged with a lock icon in the folder tree, grid, and list. `MSTV_Repository_Permissions::folders_with_rules()` returns the ruled folder IDs in one query, surfaced via `MSTV_Permissions::ruled_folder_ids()` and the `has_rules` flag added to folder REST payloads. - Improvement: the empty-folder state now renders a dashed drop zone with "Browse files" and "New folder" call-to-action buttons (gated by the upload/manage permissions), replacing the plain placeholder. The no-results search state is unchanged. - Improvement: accessibility. Raised the muted text color to meet WCAG AA contrast, added `aria-label` to the toast close button, and gave toasts `role="status"`/`role="alert"` with an appropriate `aria-live` so screen readers announce success and error messages. - Removed: white-label branding. The "Branding" settings section, the brand-name/logo/accent options, their save handling and Settings API registration, the `MSTV_Settings` branding getters, the `wp_enqueue_media()` logo picker, and the `applyBranding()`/`bindBrandLogoPicker()` client code were all removed. The admin menu and sidebar now always use the TeamVault name and logo. Existing `mstv_white_label_enabled` / `mstv_brand_*` options are deleted on upgrade (and on uninstall). Removing this cosmetic, non-core feature keeps the plugin focused on secure document management and reduces the settings surface. ## 3.1.1 - 2026-07-06 - Feature: the interface language selector gained an "Automatic (match WordPress language)" option, which is now the default. `MSTV_I18n::get_language()` resolves `auto` via `determine_locale()` and maps the WordPress locale prefix to a shipped TeamVault language (it/fr/es/de), falling back to English for any other locale. `sanitize_language()` accepts `auto`; an explicit language choice still overrides the WordPress locale. - Change: new installs default to `auto` instead of `en`, so the plugin interface matches the WordPress language out of the box. Installs that previously saved an explicit language keep it. ## 3.1.0 - 2026-07-06 - Feature: full in-admin interface localization. The custom gettext-filter translation layer (`MSTV_I18n`) now ships complete Italian, French, Spanish, and German maps (314 strings each) alongside the English source; the interface language selector on the settings page exposes all five, and `sanitize_language()`/`get_language()` accept the new codes. Every user-facing label, warning, and error message is translated, with printf placeholders preserved across all languages. - Improvement: reviewed the Italian translation and fixed genuine errors — "capability" was mistranslated as "capacità", "rinominazione" corrected to "rinomina", a dropped object in "Errore durante lo spostamento del file", "Collapse" corrected from "Raccogli" to "Comprimi", register inconsistencies made consistently informal, and a few "upload"/"storage" terms harmonized. - Docs: the GitHub README is now available in Italian, French, Spanish, and German (`README.it.md`, `README.fr.md`, `README.es.md`, `README.de.md`) with a language switcher, for international discoverability. These repository-only files are excluded from the shipped plugin package. - Tests: the i18n coverage test now asserts that every language map covers exactly the same set of translatable strings, with no missing, unused, or duplicate keys. ## 3.0.0 - 2026-07-06 - Security: the REST search endpoint now filters results through the per-folder permission engine (`viewable_folder_scope()` in the controller, constrained at the SQL level in `MSTV_Repository_Files::search_paginated()`). Previously a user with plugin access could enumerate file names, sizes, and folder association for files inside folders they had been denied. Added regression coverage in `PDMRestControllerTest`. - Security: `MSTV_Helpers::create_protection_files()` now writes an Apache 2.4-native `Require all denied` block (guarded by `mod_authz_core`) alongside the legacy Apache 2.2 `Order/Deny` fallback and the `mod_rewrite` fallback, so the storage `.htaccess` is effective on Apache 2.4 hosts that lack `mod_access_compat`. The existing IIS `web.config` and the settings-screen Nginx notice are unchanged. - Reliability: quota enforcement is now race-safe. `MSTV_Quota` acquires a named MySQL advisory lock (`GET_LOCK`) around the check-and-insert window in `upload_file()`, released in a `finally` block, so concurrent uploads can no longer both pass the quota check before either row is committed and jointly exceed the limit. The lock is best-effort (10s timeout) and a no-op when quotas are disabled. - Feature: HTTP Range support for downloads and inline previews. `MSTV_Binary_Stream::stream_binary()` advertises `Accept-Ranges: bytes`, answers a single satisfiable range with `206 Partial Content` and the correct `Content-Range`, returns `416` for unsatisfiable ranges, and otherwise streams the full file with `200`. Enables resumable downloads and range-seeking PDF viewers for large files. - Governance: `get_folder_permissions()` now returns a `default_access_open` flag (rules exist somewhere but none on the virtual root), and the permissions modal renders a warning banner so administrators are alerted that unruled folders remain accessible to every vault user. - Interface: the admin menu icon is now a filled monochrome folder painted with a CSS mask and `currentColor`, so it recolors on hover and when active exactly like a native Dashicon across all admin color schemes, and is vertically centered with the label. - Fix: `admin-notice-dismiss.js` swallows a failed dismissal request instead of leaving an unhandled promise rejection; the reports view guards on `res.success` before reading `res.data`; and computed metadata fields (`file_size_formatted`, `created_at_human`) are HTML-escaped on render. - Code quality: the 3,500-line `admin-app.js` was split into `admin-app-core.js`, `admin-app-governance.js`, and `admin-app.js`, assembled at runtime on `window.PDM` via `Object.assign` and enqueued in dependency order; behavior is unchanged (verified by method-equivalence diff and runtime load test). White-label options are now registered via `register_setting()`, the dead `MSTV_Settings::init()` was removed, and a duplicate localized i18n key was dropped. ## 2.6.3 - 2026-06-10 - Admin UI: fixed the file/folder details panel close (X) button on desktop. The button was rendered but inactive because `closeDetails()` only acted in drawer mode; on desktop it now clears the panel back to the empty state and removes the selection highlight from the grid item. In drawer mode (viewport <= 1200px) the button continues to slide the panel away as before. ## 2.6.2 - 2026-06-10 - Code quality: extracted shared binary streaming logic into a reusable `MSTV_Binary_Stream` trait, eliminating duplicate `stream_absolute_file()` implementations across download and preview handlers. - Code quality: added server-side `error_log()` diagnostics for file-not-readable and stream-failure conditions in download and preview handlers; errors go to the server log only, not to the user. - Code quality: moved the storage security notice dismiss script from an inline `