Commit Graph

5 Commits

Author SHA1 Message Date
jmiller 7532446e46 refactor: sitemap throttle + SEF URLs (#100) and batch cursor pagination (#106)
Generic: Project CI / Lint & Validate (pull_request) Successful in 13s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: PR Check / Secret Scan (pull_request) Successful in 6s
Universal: PR Check / Validate PR (pull_request) Failing after 5s
Branch Cleanup / Delete merged branch (pull_request) Failing after 1s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Failing after 10s
Generic: Project CI / Tests (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
#106 — BatchController now paginates by id cursor (WHERE c.id > :lastId)
instead of always querying offset 0. A row that fails to insert falls behind
the cursor and is not re-fetched, so the batch always terminates and reaches
100% even with persistent failures. process() returns examined + last_id; the
editor JS drives the cursor and stops when a chunk examines 0 rows.

#100 — Sitemap:
- Throttle: regenerate at most once per 60s on content save (SITEMAP_MIN_INTERVAL)
  so bulk edits/imports don't rebuild the whole file every save
- SEF URLs: route each article via Route::link('site', ...) with a fallback to
  the non-SEF index.php URL if routing fails (worst case = prior behavior)
(access-level filtering + atomic write were done earlier in the cycle)
2026-06-29 12:17:37 -05:00
jmiller 71a102028d fix: security & correctness batch (#99, #100, #101, #102, #106)
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 16s
#99 — AI AJAX endpoint hardening:
- require core.edit/core.create on com_content before generating (was
  reachable by any authenticated back-end user → paid-credit abuse)
- callAiApi: 20s timeout + HTTP status check (throw on non-200) instead of
  silently returning an empty string

#100 — Sitemap information disclosure + robustness:
- filter to public (guest) view levels so registered/special-access
  articles are never written into the public sitemap
- atomic write (temp file + rename) so concurrent saves can't expose a
  half-written sitemap.xml
- (throttling + SEF URLs remain follow-ups, noted on the issue)

#101 — Expose newer columns in CSV + API:
- og_video, event_data, recipe_data, custom_schema added to CSV export/import
  (appended, so existing CSVs still import) and to the REST API field whitelist
- import validates JSON fields as arrays/objects and og_video as http(s)
  (prevents re-introducing the #97 scalar-JSON-LD crash via import)

#102 — Forward-compat (complete):
- Factory::getLanguage() -> getApplication()->getLanguage() (4 sites)
- Joomla\CMS\Filesystem\File/Folder -> Joomla\Filesystem\* (ImageHelper, ImageGenerator)

#106 — partial: loadArticle() now caches null misses (array_key_exists),
getArticleDate() skips 0000-00-00 dates. Batch-JS halt deferred — the
offset=0 design re-fetches failed rows, so the created>0 guard prevents an
infinite loop; a safe fix needs cursor-based pagination in BatchController.
2026-06-29 09:52:51 -05:00
jmiller d6fb2816cf refactor: replace Joomla-7-deprecated APIs (forward compatibility)
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 15s
Removes accessors deprecated in Joomla 5 and slated for removal in 7
(extension already runs on 6; this future-proofs for 7):
- Factory::getDbo() -> Factory::getContainer()->get(DatabaseInterface::class)
  across plugins, controllers, static helpers, and the install script
- Factory::getUser() -> Factory::getApplication()->getIdentity()
- Factory::getSession() -> Factory::getApplication()->getSession()
- jexit(Text::_('JINVALID_TOKEN')) -> throw new \RuntimeException(..., 403),
  consistent with the access-denied checks already in those controllers

Note: SQL update-version concern is already resolved — the release bumped
to 01.05.00, which matches the 01.05.00.sql update slot.
2026-06-28 14:47:34 -05:00
jmiller b77054b769 fix: harden input handling and output safety (#79)
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 4s
Universal: PR Check / Secret Scan (pull_request) Successful in 6s
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 11s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Failing after 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 13s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
- canonical_url: sanitize via sanitizeUrl() (scheme allowlist) instead of
  bare trim() — closes stored-XSS via addHeadLink() on the public frontend
- AI endpoint: replace die('Invalid Token') with a clean event result,
  and strip_tags + truncate article_title to 200 chars before use
- SitemapBuilder: whitelist changefreq against the sitemap spec enum,
  intval() noindex IDs, strict in_array comparison
- MokoOG: log a WARNING when sitemap.xml write fails instead of ignoring it
2026-06-28 13:55:14 -05:00
Jonathan Miller 49d644566a feat: add custom schema, AI generation, XML sitemap, platform images
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 11s
- Custom JSON-LD schema builder: per-article textarea for arbitrary
  structured data with JSON validation. Closes #70
- AI-powered meta generation: Generate with AI buttons for OG title
  and description, supports Claude and OpenAI APIs. Closes #71
- XML sitemap: auto-generates sitemap.xml on article save, respects
  noindex directives. Closes #72
- Per-platform image resizing: Twitter 1200x600, Pinterest 1000x1500,
  WhatsApp 400x400 alongside default Facebook 1200x630. Closes #74
- DB migration 01.05.00: adds custom_schema column
2026-06-23 12:54:01 -05:00