Skip to content

BizzCMS 0.2.9

Choose a tag to compare

@idubravac idubravac released this 23 Oct 17:51
· 24 commits to main since this release

Security

  • Engine 3.0.0-beta.28-bizzcms.1 (from BizzCMS/bizzcms-core): seed-admin only in development/test, production refuses to run without JWT_SECRET, OAuth never links an account by e-mail alone, escaped admin user and form pages, sandboxed SVG/HTML uploads with nosniff, admin-only /api/system/info|stats|env, admin permission check fails closed, admin scripts pinned with integrity hashes.
  • Better Auth 1.6.33 (latest 1.6), pinned with overrides (better-auth, @better-auth/core, @better-auth/drizzle-adapter, @better-auth/telemetry). Sites copy the same overrides.

Added

  • Schema map for AI agents (SEO › Indexing, on by default): /schemamap.xml lists one structured-data feed per content type (/schema/<part>.ndjson, newline-delimited JSON: organisation and website once, then every published, indexable post as Article and page or collection item as WebPage). Same layout as NLWeb schema maps, so AI agents can read a whole site in one request. Follows the sitemap rules, is listed in robots.txt (Schemamap:), kept at the edge until content changes, and shown in SEO › AI Discovery. seoSitemap() answers the new paths; sites with their own sitemap call seoSchemaMap(url, db).
  • Image source records (engine 3.0.0-beta.28-bizzcms.10): every image in the media library can store its source link, author and licence (Admin > Media > file details; stored only, never shown on public pages). upload_media takes source (link to the original page), credit and license; the old free-text source is no longer copied into the caption (Izvor: ...), so nothing about the source can reach a page.
  • E-mail confirmation for site accounts: configureAccounts({ confirmSince }) makes every account opened from that moment (by any route) confirm its e-mail before it can be used: the sign-up sends a link (hashed, valid 7 days) instead of signing in, sign-in is refused and a session from elsewhere is ignored until confirmed, "send the link again" never reveals whether an account exists. Older accounts, Google sign-ups and invitation activations are not affected. New texts confirm*, paths confirm/confirmed, e-mail confirmEmail; the registered hook and the welcome e-mail follow the confirmation.
  • Table setup once per deploy (src/schema-once.ts): the shared files' CREATE TABLE IF NOT EXISTS and plugin-record steps run once per isolate, and once per deploy with configureSchemaOnce({ kv, deployId }) plus [version_metadata] in wrangler.toml (docs/caching.md). Engine 3.0.0-beta.28-bizzcms.9 does the same for its bootstrap.
  • Directory plugin: featuring: featuredUntil on a profile puts it first in the default and Recommended order, suggestions and featured lists, with a "Featured" label (text.featured); Plan.featureMonths.
  • Directory plugin: imported owners: activation lets an account without a password (imported from an old site) set one and signs it in; ownerPending on the profile is cleared. signInSession() in site-accounts.
  • Directory plugin: params.defaultSort: the order used when the address has no sort (e.g. newest first); that order needs no parameter and Recommended gets its own value (params.sortRecommended).
  • Directory plugin: notify hook: setDirectory({ notify }) is called after a date request, a profile claim or a new company profile is saved (DirectoryEvent), e.g. to send e-mail; errors never fail the save.
  • Directory plugin: region (county) pages: optional routes.region (e.g. /companies/region/{slug}/) gives each region a clean, indexable page in the sitemap; a region chosen in the filter redirects there; regionUrl().
  • Directory plugin: clean filter addresses: empty parameters are dropped (301), a directory search with a category or city goes to that category/city page with the other filters (?region=…&guests=…), and GET forms no longer send empty fields.
  • Directory plugin: taxonomy.priceFilter (default true): false hides the price filter in the directory sidebar; price levels stay on profiles and in the portal.
  • Directory plugin: unique profile titles: Name - (sub)category, city when the company has no own SEO title (an imported SEO title equal to the name counts as none), so same-named companies never share a <title>.
  • MCP publish date: create_<collection> and publish_<collection> take an optional publishedAt (ISO 8601 date or date-time, or unix seconds; not in the future), so imported or historical articles go live with their own date and sort correctly (docs/mcp.md › Publish dates).
  • MCP upload_media: adds an image from an https link or base64 to the media library in the site's own folder and returns the /files/... path for featuredImage; alt text, caption, tags and a source/licence note are stored. Safe fetch: https only, no IP addresses or internal host names, redirects checked, JPEG/PNG/WebP/GIF/AVIF only, 10 MB at most; the link (which may carry a key) is never stored or echoed. Listed only for callers with write access (docs/mcp.md › Media upload).
  • MCP categories: list_/get_/create_/update_/publish_/delete_categories, with read and write following the per-collection MCP access settings.
  • MCP unique slugs: create_<collection> refuses a slug that an existing item of that collection already uses.
  • All MCP additions live in src/mcp-extras.ts; sites route POST /mcp through mcpWithExtras(request, db, upstream, { mediaFolder }).

Fixed

  • MCP writes did not renew the edge cache: pages caught up after a few minutes, but sitemaps and feeds stayed old until the next save in the admin. A successful MCP create, update, publish or delete now renews it like an admin save.
  • docs/mcp.md listed tool names that do not exist (create_page, create_post); the tools are create_<collection>, update_…, publish_…, delete_….

Changed

  • MCP: "MCP Settings" is a black button right after the Settings / Information / Activity Log tabs on the MCP plugin page (was a banner above the page). The "Collection write access" card sits in the MCP dashboard's column in the same card style, and the example configs name the server bizzcms.