Skip to content

Releases: youssefboutaleb/kanboard-file-attachment-interaction

v1.1.1

Choose a tag to compare

@github-actions github-actions released this 18 Aug 14:03

Licensing and documentation follow-up to 1.1.0. No functional change — no behaviour,
route, handler or permission check differs from 1.1.1's predecessor.

Added

  • MIT license banner on Assets/js/vendor/pptx-viewer.umd.js. The bundle shipped in every
    previous release carrying no license, copyright, version or origin of any kind, which made
    it indistinguishable from unattributed third-party code to anyone reviewing the archive —
    a listing risk for the plugin directory. It is first-party work by the copyright holder and
    is covered by this project's own MIT license.

Changed

  • NOTICE now classifies each bundle in Assets/js/vendor/ as first-party or third-party,
    and records that docx-preview stays Apache-2.0 inside this MIT work — permitted, since
    Apache-2.0 is permissive and its attribution travels with it in NOTICE.
  • scripts/patch_pptx_viewer.js header rewritten: now that the bundle is known to be
    first-party, the correct fix is to fold its six patches into the bundle's own source and
    delete this script, rather than patching a build artifact after every rebuild.
  • docs/kanboard-directory-submission.md unblocked and ready to submit.
  • docs/CONTRIBUTABILITY_REPORT.md verdict raised to READY.

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 18 Aug 13:48

Security release. Upgrading is strongly recommended for every installation.

Security

  • Fixed cross-project attachment disclosure and overwrite (object-level authorization / IDOR).
    Kanboard authorizes these routes through projectAccessMap, which proves the caller
    holds a role on the project_id in the URL and inspects nothing about file_id.
    The controllers meanwhile loaded attachments with getById($fileId), keyed on the id
    alone, and only fell back to the row's own task_id/project_id when the URL values
    were 0 — so on the real routes the file's true owner was never compared to anything.

    Any user could therefore name a project they legitimately belong to in the path and a
    foreign attachment id in the query:

    /b/<project the caller can access>/task/<any>/file/<file in a FOREIGN project>/preview
    

    The ACL passed and the foreign file's bytes were previewed, streamed, opened in the
    editor, or — through FileEditController::update()overwritten.

    HandlesAttachmentInteraction::assertAttachmentOwnership() now joins file_id to the
    task and project named in the URL before any bytes are read, on all four actions
    (preview, stream, edit, update). Covered by tests/Unit/AttachmentAuthorizationTest.php.

  • Fixed the plugin's ACL layer being inert at runtime.
    PermissionService defaulted to MockPermissionChecker(true) — an allow-everything
    stub written for unit tests — and no controller ever injected anything else, so every
    canUserReadFile() / canUserWriteFile() call returned true in production. The new
    KanboardPermissionChecker is backed by Kanboard's own projectPermissionModel and
    userSession and is installed automatically whenever the container provides them. It
    fails closed: a checker that cannot reach the models it needs answers "no".

  • Project viewers can no longer overwrite attachments.
    canUserWriteFile() aliased canUserReadFile(), so read access implied write access.
    Write now requires isMember() rather than isUserAllowed().

Added

  • Plugin::getCompatibleVersion() returning >=1.2.23 — the release in which Kanboard
    added the template:project-overview:documents:dropdown hook this plugin attaches to.
    Without the override, the inherited default claims compatibility with whatever core is
    running and the hook fails silently on older versions.
  • NOTICE recording the license and provenance of the bundled third-party JavaScript.
  • tests/Integration/PackagingTest.php and tests/bootstrap.php.

Changed

  • Packaging is now an allow-list. The exclude-based rsync shipped CLAUDE.md,
    AGENTS.md, implementation_plan.md, settings.json, .phpunit.result.cache and
    154 KB of walkthrough.md to end users. The archive now contains only the runtime plus
    LICENSE/NOTICE/README/CHANGELOG, and the build fails if a development file
    appears in it or if the archive root entry is not FileInteractionCore/.
  • Licensing is consistent. LICENSE and the metadata had drifted apart — the LICENSE
    file said one thing while composer.json and the README said another. Everything now
    declares MIT, matching the LICENSE file, and tests/Integration/PackagingTest.php
    fails if they ever disagree again.

Removed

  • Assets/js/preview-language-selector.js — a verbatim duplicate of the language-picker
    handler already in preview-controls.js. Both registered their own delegated change
    listener, so a single language change fired two KB.modal.replace() calls and the
    modal was fetched and rebuilt twice.
  • require_once __DIR__ . '/../../tests/stubs/BaseController.php' from
    FilePreviewController and FileStreamController. Production classes must not
    reference tests/, which the release archive excludes; the stub now loads from
    tests/bootstrap.php instead.

Known issues

  • Assets/js/vendor/pptx-viewer.umd.js has unresolved provenance — no license
    banner, copyright, version or upstream identifier. See NOTICE. This must be closed
    before the plugin is submitted to the Kanboard plugin directory or a release archive
    containing it is published.

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 18 Aug 12:06

Author Metadata Update & Patch Release.

Changed

  • Updated plugin author metadata to Youssef BOUTALEB in Plugin.php, composer.json, and technical specifications.
  • Bumped plugin version to 1.0.1.

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 01:53

Production Architecture Refactoring, Visual Documentation & Open-Source Release.

Added

  • AbstractPreviewHandler: Centralized base class encapsulating size truncation, line counting, character counting, string normalization, and output escaping across all format strategies.
  • HandlesAttachmentInteraction Trait: Shared concern trait unifying container probing, attachment metadata lookup, project ID resolution, traversal-safe storage reads, layout rendering, and error modals across controllers.
  • CONTRIBUTING.md: Comprehensive open-source contributor guide with coding standards, architecture diagrams, step-by-step handler implementation guide, and testing workflows.
  • Visual Technical Diagrams:
    • Security & Safety Model diagram in README.md and docs/SECURITY.md illustrating the multi-layer defense-in-depth architecture.
    • System Component Architecture and Interaction Lifecycle Sequence diagrams in docs/ARCHITECTURE.md.
  • GitHub Release & Open Source Documentation in README.md: Complete feature breakdown, supported format table, step-by-step release archive installation, Git setup, and Docker testing.
  • Strategic Next-Generation Roadmap in docs/ROADMAP.md: Strategic evolution plan spanning v1.0.0 through v2.0.0 (visual revision diffs, full-text search, external office document servers).

Changed

  • Refactored all concrete handlers (TextPreviewHandler, HtmlPreviewHandler, MarkdownPreviewHandler, JsonPreviewHandler, CodePreviewHandler, DocxPreviewHandler, PptxPreviewHandler, ExcelPreviewHandler, PdfPreviewHandler, CsvPreviewHandler) to extend AbstractPreviewHandler.
  • Refactored FilePreviewController, FileEditController, and FileStreamController to use HandlesAttachmentInteraction.
  • Modernized phpunit.xml removing deprecated verbose attribute and migrating coverage nodes to PHPUnit 10 <source> schema.
  • Bumped plugin version to 1.0.0 in Plugin.php.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 01:29

DOCX & PPTX Document Preview Engine.

Added

  • High-Fidelity In-Browser Office Document & Presentation Preview Engines:
    • docx-preview.min.js & jszip.min.js: Client-side high-fidelity Word document rendering preserving pagination, margins, typography, tables, drawings, and embedded images.
    • pptx-viewer.umd.js: Client-side high-fidelity PowerPoint presentation rendering preserving slide aspect ratios, background themes, shapes, typography, tables, and slide deck layout.
    • Assets/js/office-viewer.js: Automated controller initializing .fic-docx-container and .fic-pptx-container viewers, fetching binary payloads via stream routes, and providing slide navigation controls (Prev, Next, slide counter, tabs, keyboard shortcuts).
    • Stream route integration in FileStreamController with docx, dotx, pptx, potx in INLINE_MIME_TYPES and MAGIC_SIGNATURES.
  • OpenXML Word Document (.docx, .dotx, .doc) Preview Engine:
    • DocxParserService: Pure-PHP memory-safe OpenXML DOM parser extracting headings (H1-H4), formatted text runs (bold, italic, underline, strike, monospace code), bullet/numbered lists, and tables with pre-escaped HTML (htmlspecialchars()).
    • DocxPreviewHandler: Handler for Word documents returning structured HTML and metadata (paragraphCount, headingCount, tableCount, wordCount). Gracefully detects legacy .doc (OLE2 binary format) to emit safe download notices without memory bloat.
    • Template/file/docx_preview.php: Word Document reading pane with summary badges and clean typography.
  • OpenXML PowerPoint Presentation (.pptx, .potx, .ppt) Preview Engine:
    • PptxParserService: Pure-PHP memory-safe presentation parser resolving slide ordering via ppt/presentation.xml & ppt/_rels/presentation.xml.rels, extracting slide titles, bullet points, text blocks, and structured slide tables.
    • PptxPreviewHandler: Handler for PowerPoint presentations returning slide deck arrays and metadata (slideCount, title). Gracefully detects legacy .ppt format.
    • Template/file/pptx_preview.php: Interactive presentation viewer with slide switcher tabs (Slide 1, Slide 2...), active slide canvas, and presentation title header.
  • Expanded Test Suite:
    • 30 new unit and integration tests covering synthetic OpenXML ZIP document & presentation parsing, slide ordering, bullet point extraction, table extraction, legacy format notices, streaming MIME types, and template rendering (total 755 tests, 2562 assertions).

Changed

  • Updated FileValidationService to whitelist docx, dotx, doc (10 MB cap) and pptx, potx, ppt (15 MB cap) with strict MIME mappings.
  • Updated PreviewViewModeRegistry with "Word Document" and "PowerPoint Presentation" labels.
  • Updated FilePreviewController to register DocxPreviewHandler and PptxPreviewHandler and route to docx_preview and pptx_preview templates.
  • Updated Template/file/dropdown.php to include docx and pptx extensions in the Safe Preview menu.
  • Bumped plugin version to 0.9.0 in Plugin.php.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 08 Aug 17:00

Added

  • Excel Spreadsheet Interactive Preview Engine:
    • ExcelParserService: Memory-safe .xlsx OpenXML parser extracting sheet names (xl/workbook.xml), shared string lookup tables (xl/sharedStrings.xml), and row/column data matrices capped at 100 rows x 50 columns.
    • ExcelPreviewHandler: Handler supporting .xlsx and .xls attachments, returning multi-sheet workbook structure and metadata.
    • Template/file/excel_preview.php: Multi-sheet tabbed spreadsheet modal view with worksheet navigation tabs (Sheet1, Sheet2), A/B/C column headers, row index gutter, cell HTML entity escaping, and legacy format / truncation banners.
    • Added 'xlsx' and 'xls' extensions to attachment dropdown whitelist (Template/file/dropdown.php) with 5 MB file size caps in FileValidationService.
  • Expanded Test Suite:
    • 39 new unit & integration tests covering OpenXML spreadsheet parsing, multi-sheet tab rendering, legacy .xls notification, XSS cell escaping, and 5 MB size cap enforcement (total 279 tests, 925 assertions).

Fixed

  • Registered ExcelPreviewHandler in FilePreviewController handler registry (7-handler registry order).

Changed

  • Updated Plugin.php version to 0.6.0.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 08 Aug 15:14

Added

  • Safe In-App Text & JSON Live Editor:
    • FileEditController: Live editor controller handling edit() modal rendering and update() POST save actions.
    • FileEditValidationService: Pre-save validation engine checking payload size bounds (500 KB limit) and JSON syntax error line detection (json_decode() error reporting).
    • FileVersionService: Attachment revision engine supporting overwrite updates and versioned revision file creation (filename_v2.ext).
    • Template/file/edit.php: Interactive editor modal view with syntax status indicators, line-number gutter, live character counters, and save mode selection (overwrite vs revision).
    • "Edit File" action link added to file attachment dropdown (Template/file/dropdown.php) for text/JSON/Markdown attachments when user has write access.
  • Expanded Test Suite:
    • 54 new unit & integration tests covering pre-save validation, JSON syntax error estimation, version filename generation, edit modal rendering, and write ACL enforcement (total 240 tests, 789 assertions).

Changed

  • Updated Plugin.php version to 0.5.0 and registered /b/:project_id/task/:task_id/file/:file_id/edit and update routes.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 08 Aug 01:25

Added

  • PDF Embedded Read-Only Viewer Engine:
    • PdfPreviewHandler: Binary-safe handler for .pdf attachments and application/pdf / application/x-pdf MIME types. The payload is never parsed, decoded, or executed — only size metadata is emitted.
    • Template/file/pdf_preview.php: Embedded modal viewer streaming the document into an <object type="application/pdf"> container through Kanboard core's inline FileViewerController::browser action.
    • Graceful fallback banner with a secure download link (rel="noopener noreferrer") for browsers without an inline PDF renderer.
    • Dedicated 10 MB size ceiling for PDF attachments.
  • Per-Extension Size Cap Mechanism:
    • FileValidationService::EXTENSION_MAX_SIZE_BYTES overrides the global 500 KB default on a per-format basis; validateFileSize() accepts an optional $extension argument.
    • getMaxSizeForExtension() accessor, with constructor-injectable caps for testing.
  • Test Suite Expansion:
    • 44 new unit & integration tests covering PDF handler resolution, registration precedence, 10 MB boundary enforcement, MIME spoofing rejection, modal template dispatching, inline-vs-download URL targeting, and filename escaping (total 186 tests, 582 assertions).

Changed

  • Updated FileValidationService to whitelist pdf. MIME_MAP['pdf'] accepts application/pdf, application/x-pdf, and application/octet-stream, and deliberately rejects text/* — a PDF announcing itself as renderable text is treated as a spoofing attempt.
  • Updated FilePreviewController to register 6 format handlers with PdfPreviewHandler FIRST, so binary payloads never fall through to the TextPreviewHandler text/* catch-all, and to dispatch FileInteractionCore:file/pdf_preview.
  • Updated Template/file/dropdown.php to expose "Safe Preview" for .pdf attachments.
  • Bumped plugin version to 0.4.0 in Plugin.php and composer.json.

Fixed

  • PDF viewer <object> container now targets the inline browser action instead of download. The download action sets Content-Disposition: attachment, which made browsers open a save dialog instead of rendering the document inside the modal.

Build & CI

  • Removed the top-level version field from composer.json. It made composer validate --strict exit non-zero, failing the GitHub Actions CI job. Plugin.php::getPluginVersion() is now the single source of truth, and scripts/package-plugin.sh reads the archive version from it.
  • dist/ is now git-ignored. Release archives are published as GitHub Release assets by the new .github/workflows/release.yml, which fires on v* tag pushes, verifies the tag matches Plugin.php, and uses the matching CHANGELOG.md section as release notes.

Known Limitations

  • Spec 004 AC-3 specifies a sandbox attribute, which the HTML <object> element does not support (it is an <iframe>-only attribute). Script containment currently relies on the browser's built-in PDF viewer. Migrating the container to a sandboxed <iframe> is tracked as a follow-up.