Skip to content

v1.0.0 — First stable release

Choose a tag to compare

@dta121 dta121 released this 19 May 19:17
· 33 commits to main since this release

First stable release. Plugin is now MATURITY_STABLE.

This release lands eight findings from an internal security audit, adds a PHPUnit test suite covering the new gates, and expands CI to every supported Moodle version.

🔒 Security

ID Title What it does
F1 Hidden chapter gate get_status, request_regen, and the pluginfile handler now reject hidden book chapters unless the caller has mod/book:viewhiddenchapters. Previously a learner with module-level access could narrate any chapter id.
F2 Lang allowlist enforcement The lang parameter on every external function is server-validated against the admin enabled_languages allowlist. Closes an OpenAI cost-amplification DoS.
F3 Pluginfile require_login scoping Uses require_login($course, false, $cm) so enrolment, course visibility, and activity availability rules all apply.
F4 Per-asset content cap New max_narration_chars admin setting (default 50000) refuses runaway pages before OpenAI is called.
F5 Unused capability removed local/aireader:purge was declared but never enforced. Gone.
F6 HTTPS-only outbound New http_guard helper rejects non-HTTPS endpoints, loopback, RFC1918 private addresses, link-local, and the cloud metadata service. Curl is locked to CURLPROTO_HTTPS.
F7 OpenAI error sanitization Bearer tokens, sk-… keys, and 40+ char opaque identifiers are redacted before being stored on the asset row or written to cron logs.
F8 Narrower web service return types Segment text now PARAM_NOTAGS, status messages PARAM_TEXT (previously PARAM_RAW).

✅ Testing

  • 31 PHPUnit tests across 5 files covering the URL guard, error sanitizer, override resolution chain, translation cache LRU, asset_manager helpers, and the get_status security gates.

🔁 CI

  • Matrix expanded from Moodle 4.5 only to Moodle 4.5 LTS / 5.0 / 5.1 / 5.2 on PHP 8.1 / 8.2 / 8.3 / 8.4 across both PostgreSQL 16 and MariaDB 10.11.
  • actions/checkout bumped to v5 (Node.js 24) ahead of GitHub's 2026-06-02 Node 20 deprecation.
  • Grunt step no longer has continue-on-error; CSS regressions and AMD-build drift now fail loudly.
  • Stylelint clean.

📦 Migration notes

  • No schema change. The upgrade savepoint at 2026051900 registers the max_narration_chars admin default; nothing else moves.
  • If you had a custom role using local/aireader:purge, that capability is gone — but it was a no-op anyway, so role behavior is unchanged.

📜 Full changelog

See CHANGELOG.md for the complete history from 0.1.0 through 1.0.0.